Skip to content

Commit

Permalink
Add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
adrianmoisey committed Jun 26, 2024
1 parent 8d2bbb8 commit 1b36617
Show file tree
Hide file tree
Showing 3 changed files with 230 additions and 4 deletions.
72 changes: 69 additions & 3 deletions vertical-pod-autoscaler/pkg/admission-controller/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,10 @@ func TestSelfRegistrationBase(t *testing.T) {
url := "http://example.com/"
registerByURL := true
timeoutSeconds := int32(32)
selectedNamespaces := []string{}
ignoredNamespaces := []string{}

selfRegistration(testClientSet, caCert, namespace, serviceName, url, registerByURL, timeoutSeconds)
selfRegistration(testClientSet, caCert, namespace, serviceName, url, registerByURL, timeoutSeconds, selectedNamespaces, ignoredNamespaces)

webhookConfigInterface := testClientSet.AdmissionregistrationV1().MutatingWebhookConfigurations()
webhookConfig, err := webhookConfigInterface.Get(context.TODO(), webhookConfigName, metav1.GetOptions{})
Expand Down Expand Up @@ -75,8 +77,10 @@ func TestSelfRegistrationWithURL(t *testing.T) {
url := "http://example.com/"
registerByURL := true
timeoutSeconds := int32(32)
selectedNamespaces := []string{}
ignoredNamespaces := []string{}

selfRegistration(testClientSet, caCert, namespace, serviceName, url, registerByURL, timeoutSeconds)
selfRegistration(testClientSet, caCert, namespace, serviceName, url, registerByURL, timeoutSeconds, selectedNamespaces, ignoredNamespaces)

webhookConfigInterface := testClientSet.AdmissionregistrationV1().MutatingWebhookConfigurations()
webhookConfig, err := webhookConfigInterface.Get(context.TODO(), webhookConfigName, metav1.GetOptions{})
Expand All @@ -100,8 +104,10 @@ func TestSelfRegistrationWithOutURL(t *testing.T) {
url := "http://example.com/"
registerByURL := false
timeoutSeconds := int32(32)
selectedNamespaces := []string{}
ignoredNamespaces := []string{}

selfRegistration(testClientSet, caCert, namespace, serviceName, url, registerByURL, timeoutSeconds)
selfRegistration(testClientSet, caCert, namespace, serviceName, url, registerByURL, timeoutSeconds, selectedNamespaces, ignoredNamespaces)

webhookConfigInterface := testClientSet.AdmissionregistrationV1().MutatingWebhookConfigurations()
webhookConfig, err := webhookConfigInterface.Get(context.TODO(), webhookConfigName, metav1.GetOptions{})
Expand All @@ -117,3 +123,63 @@ func TestSelfRegistrationWithOutURL(t *testing.T) {

assert.Nil(t, webhook.ClientConfig.URL, "expected URL to be set")
}

func TestSelfRegistrationWithIgnoredNamespaces(t *testing.T) {

testClientSet := fake.NewSimpleClientset()
caCert := []byte("fake")
namespace := "default"
serviceName := "vpa-service"
url := "http://example.com/"
registerByURL := false
timeoutSeconds := int32(32)
selectedNamespaces := []string{}
ignoredNamespaces := []string{"test"}

selfRegistration(testClientSet, caCert, namespace, serviceName, url, registerByURL, timeoutSeconds, selectedNamespaces, ignoredNamespaces)

webhookConfigInterface := testClientSet.AdmissionregistrationV1().MutatingWebhookConfigurations()
webhookConfig, err := webhookConfigInterface.Get(context.TODO(), webhookConfigName, metav1.GetOptions{})

assert.NoError(t, err, "expected no error fetching webhook configuration")

assert.Len(t, webhookConfig.Webhooks, 1, "expected one webhook configuration")
webhook := webhookConfig.Webhooks[0]

assert.NotNil(t, webhook.NamespaceSelector.MatchExpressions, "expected namespace selector not to be nil")
assert.Len(t, webhook.NamespaceSelector.MatchExpressions, 1, "expected one match expression")

matchExpression := webhook.NamespaceSelector.MatchExpressions[0]
assert.Equal(t, matchExpression.Operator, metav1.LabelSelectorOpNotIn, "expected namespace operator to be OpNotIn")
assert.Equal(t, matchExpression.Values, ignoredNamespaces, "expected namespace selector match expression to be equal")
}

func TestSelfRegistrationWithSelectedNamespaces(t *testing.T) {

testClientSet := fake.NewSimpleClientset()
caCert := []byte("fake")
namespace := "default"
serviceName := "vpa-service"
url := "http://example.com/"
registerByURL := false
timeoutSeconds := int32(32)
selectedNamespaces := []string{"test"}
ignoredNamespaces := []string{}

selfRegistration(testClientSet, caCert, namespace, serviceName, url, registerByURL, timeoutSeconds, selectedNamespaces, ignoredNamespaces)

webhookConfigInterface := testClientSet.AdmissionregistrationV1().MutatingWebhookConfigurations()
webhookConfig, err := webhookConfigInterface.Get(context.TODO(), webhookConfigName, metav1.GetOptions{})

assert.NoError(t, err, "expected no error fetching webhook configuration")

assert.Len(t, webhookConfig.Webhooks, 1, "expected one webhook configuration")
webhook := webhookConfig.Webhooks[0]

assert.NotNil(t, webhook.NamespaceSelector.MatchExpressions, "expected namespace selector not to be nil")
assert.Len(t, webhook.NamespaceSelector.MatchExpressions, 1, "expected one match expression")

matchExpression := webhook.NamespaceSelector.MatchExpressions[0]
assert.Equal(t, matchExpression.Operator, metav1.LabelSelectorOpIn, "expected namespace operator to be OpIn")
assert.Equal(t, matchExpression.Values, selectedNamespaces, "expected namespace selector match expression to be equal")
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import (
"k8s.io/autoscaler/vertical-pod-autoscaler/pkg/recommender/input/history"
"k8s.io/autoscaler/vertical-pod-autoscaler/pkg/recommender/input/spec"
"k8s.io/autoscaler/vertical-pod-autoscaler/pkg/recommender/model"
"k8s.io/autoscaler/vertical-pod-autoscaler/pkg/target/controller_fetcher"
controllerfetcher "k8s.io/autoscaler/vertical-pod-autoscaler/pkg/target/controller_fetcher"
target_mock "k8s.io/autoscaler/vertical-pod-autoscaler/pkg/target/mock"
"k8s.io/autoscaler/vertical-pod-autoscaler/pkg/utils/test"
)
Expand Down Expand Up @@ -568,3 +568,66 @@ func TestFilterVPAs(t *testing.T) {

assert.ElementsMatch(t, expectedResult, result)
}

func TestFilterVPAsIgnoreNamespaces(t *testing.T) {

vpa1 := &vpa_types.VerticalPodAutoscaler{
ObjectMeta: metav1.ObjectMeta{
Namespace: "namespace1",
},
Spec: vpa_types.VerticalPodAutoscalerSpec{
Recommenders: []*vpa_types.VerticalPodAutoscalerRecommenderSelector{
{Name: DefaultRecommenderName},
},
},
}
vpa2 := &vpa_types.VerticalPodAutoscaler{
ObjectMeta: metav1.ObjectMeta{
Namespace: "namespace2",
},
Spec: vpa_types.VerticalPodAutoscalerSpec{
Recommenders: []*vpa_types.VerticalPodAutoscalerRecommenderSelector{
{Name: DefaultRecommenderName},
},
},
}
vpa3 := &vpa_types.VerticalPodAutoscaler{
ObjectMeta: metav1.ObjectMeta{
Namespace: "ignore1",
},
Spec: vpa_types.VerticalPodAutoscalerSpec{
Recommenders: []*vpa_types.VerticalPodAutoscalerRecommenderSelector{
{Name: DefaultRecommenderName},
},
},
}
vpa4 := &vpa_types.VerticalPodAutoscaler{
ObjectMeta: metav1.ObjectMeta{
Namespace: "ignore2",
},
Spec: vpa_types.VerticalPodAutoscalerSpec{
Recommenders: []*vpa_types.VerticalPodAutoscalerRecommenderSelector{
{Name: DefaultRecommenderName},
},
},
}

allVpaCRDs := []*vpa_types.VerticalPodAutoscaler{vpa1, vpa2, vpa3, vpa4}

feeder := &clusterStateFeeder{
recommenderName: DefaultRecommenderName,
ignoredNamespaces: []string{"ignore1", "ignore2"},
}

// Set expected results
expectedResult := []*vpa_types.VerticalPodAutoscaler{vpa1, vpa2}

// Run the filterVPAs function
result := filterVPAs(feeder, allVpaCRDs)

if len(result) != len(expectedResult) {
t.Fatalf("expected %d VPAs, got %d", len(expectedResult), len(result))
}

assert.ElementsMatch(t, expectedResult, result)
}
97 changes: 97 additions & 0 deletions vertical-pod-autoscaler/pkg/updater/logic/updater_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,3 +260,100 @@ func newFakeValidator(isValid bool) status.Validator {
func (f *fakeValidator) IsStatusValid(statusTimeout time.Duration) (bool, error) {
return f.isValid, nil
}

func TestRunOnceIgnoreNamespaceMatchingPods(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()

replicas := int32(5)
livePods := 5
labels := map[string]string{"app": "testingApp"}
selector := parseLabelSelector("app = testingApp")

containerName := "container1"
rc := apiv1.ReplicationController{
TypeMeta: metav1.TypeMeta{
Kind: "ReplicationController",
APIVersion: "apps/v1",
},
ObjectMeta: metav1.ObjectMeta{
Name: "rc",
Namespace: "default",
},
Spec: apiv1.ReplicationControllerSpec{
Replicas: &replicas,
},
}
pods := make([]*apiv1.Pod, livePods)
eviction := &test.PodsEvictionRestrictionMock{}

for i := range pods {
pods[i] = test.Pod().WithName("test_"+strconv.Itoa(i)).
AddContainer(test.Container().WithName(containerName).WithCPURequest(resource.MustParse("1")).WithMemRequest(resource.MustParse("100M")).Get()).
WithCreator(&rc.ObjectMeta, &rc.TypeMeta).
Get()

pods[i].Labels = labels
eviction.On("CanEvict", pods[i]).Return(true)
eviction.On("Evict", pods[i], nil).Return(nil)
}

factory := &fakeEvictFactory{eviction}
vpaLister := &test.VerticalPodAutoscalerListerMock{}

podLister := &test.PodListerMock{}
podLister.On("List").Return(pods, nil)
targetRef := &v1.CrossVersionObjectReference{
Kind: rc.Kind,
Name: rc.Name,
APIVersion: rc.APIVersion,
}
vpaObj := test.VerticalPodAutoscaler().
WithNamespace("default").
WithContainer(containerName).
WithTarget("2", "200M").
WithMinAllowed(containerName, "1", "100M").
WithMaxAllowed(containerName, "3", "1G").
WithTargetRef(targetRef).Get()

vpaLister.On("List").Return([]*vpa_types.VerticalPodAutoscaler{vpaObj}, nil).Once()

mockSelectorFetcher := target_mock.NewMockVpaTargetSelectorFetcher(ctrl)
mockSelectorFetcher.EXPECT().Fetch(gomock.Eq(vpaObj)).Return(selector, nil)

updater := &updater{
vpaLister: vpaLister,
podLister: podLister,
evictionFactory: factory,
evictionRateLimiter: rate.NewLimiter(rate.Inf, 0),
evictionAdmission: priority.NewDefaultPodEvictionAdmission(),
recommendationProcessor: &test.FakeRecommendationProcessor{},
selectorFetcher: mockSelectorFetcher,
controllerFetcher: controllerfetcher.FakeControllerFetcher{},
useAdmissionControllerStatus: true,
priorityProcessor: priority.NewProcessor(),
ignoredNamespaces: []string{"not-default"},
statusValidator: newFakeValidator(true),
}

updater.RunOnce(context.Background())
eviction.AssertNumberOfCalls(t, "Evict", 5)
}

func TestRunOnceIgnoreNamespaceMatching(t *testing.T) {
eviction := &test.PodsEvictionRestrictionMock{}
vpaLister := &test.VerticalPodAutoscalerListerMock{}
vpaObj := test.VerticalPodAutoscaler().
WithNamespace("default").
WithContainer("container").Get()

vpaLister.On("List").Return([]*vpa_types.VerticalPodAutoscaler{vpaObj}, nil).Once()

updater := &updater{
vpaLister: vpaLister,
ignoredNamespaces: []string{"default"},
}

updater.RunOnce(context.Background())
eviction.AssertNumberOfCalls(t, "Evict", 0)
}

0 comments on commit 1b36617

Please sign in to comment.