sigs.k8s.io/kueue@v0.6.2/pkg/util/admissioncheck/admissioncheck_test.go (about)

     1  /*
     2  Copyright 2023 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package admissioncheck
    18  
    19  import (
    20  	"context"
    21  	"testing"
    22  
    23  	"github.com/google/go-cmp/cmp"
    24  	"github.com/google/go-cmp/cmp/cmpopts"
    25  	corev1 "k8s.io/api/core/v1"
    26  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    27  	"k8s.io/apimachinery/pkg/runtime"
    28  	clientgoscheme "k8s.io/client-go/kubernetes/scheme"
    29  	"sigs.k8s.io/controller-runtime/pkg/client/fake"
    30  
    31  	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta1"
    32  	utiltesting "sigs.k8s.io/kueue/pkg/util/testing"
    33  )
    34  
    35  func TestConfigHelper(t *testing.T) {
    36  	testConfig := &kueue.ProvisioningRequestConfig{
    37  		ObjectMeta: metav1.ObjectMeta{
    38  			Name: "config",
    39  		},
    40  		Spec: kueue.ProvisioningRequestConfigSpec{
    41  			ProvisioningClassName: "className",
    42  			Parameters: map[string]kueue.Parameter{
    43  				"p1": "v1",
    44  			},
    45  			ManagedResources: []corev1.ResourceName{"cpu"},
    46  		},
    47  	}
    48  
    49  	cases := map[string]struct {
    50  		admissioncheck       *kueue.AdmissionCheck
    51  		config               *kueue.ProvisioningRequestConfig
    52  		targetAdmissionCheck string
    53  		wantConfig           *kueue.ProvisioningRequestConfig
    54  		wantError            error
    55  	}{
    56  		"admission check bad name": {
    57  			targetAdmissionCheck: "123",
    58  			wantError:            cmpopts.AnyError,
    59  		},
    60  		"no parameter reference": {
    61  			admissioncheck:       utiltesting.MakeAdmissionCheck("ac").Obj(),
    62  			targetAdmissionCheck: "ac",
    63  			wantError:            ErrNilParametersRef,
    64  		},
    65  		"bad parameter reference, no name": {
    66  			admissioncheck: utiltesting.MakeAdmissionCheck("ac").
    67  				Parameters(kueue.GroupVersion.Group, "ProvisioningRequestConfig", "").
    68  				Obj(),
    69  			targetAdmissionCheck: "ac",
    70  			wantError:            ErrBadParametersRef,
    71  		},
    72  		"bad parameter reference, bad group": {
    73  			admissioncheck: utiltesting.MakeAdmissionCheck("ac").
    74  				Parameters("not-"+kueue.GroupVersion.Group, "ProvisioningRequestConfig", "config").
    75  				Obj(),
    76  			targetAdmissionCheck: "ac",
    77  			wantError:            ErrBadParametersRef,
    78  		},
    79  		"bad parameter reference, bad kind": {
    80  			admissioncheck: utiltesting.MakeAdmissionCheck("ac").
    81  				Parameters(kueue.GroupVersion.Group, "NptProvisioningRequestConfig", "config").
    82  				Obj(),
    83  			targetAdmissionCheck: "ac",
    84  			wantError:            ErrBadParametersRef,
    85  		},
    86  		"config not found": {
    87  			admissioncheck: utiltesting.MakeAdmissionCheck("ac").
    88  				Parameters(kueue.GroupVersion.Group, "ProvisioningRequestConfig", "config").
    89  				Obj(),
    90  			targetAdmissionCheck: "ac",
    91  			wantError:            cmpopts.AnyError,
    92  		},
    93  		"config found": {
    94  			admissioncheck: utiltesting.MakeAdmissionCheck("ac").
    95  				Parameters(kueue.GroupVersion.Group, "ProvisioningRequestConfig", "config").
    96  				Obj(),
    97  			config:               testConfig.DeepCopy(),
    98  			targetAdmissionCheck: "ac",
    99  			wantConfig:           testConfig.DeepCopy(),
   100  		},
   101  	}
   102  
   103  	for name, tc := range cases {
   104  		t.Run(name, func(t *testing.T) {
   105  			scheme := runtime.NewScheme()
   106  			if err := clientgoscheme.AddToScheme(scheme); err != nil {
   107  				panic(err)
   108  			}
   109  			if err := kueue.AddToScheme(scheme); err != nil {
   110  				panic(err)
   111  			}
   112  			builder := fake.NewClientBuilder().WithScheme(scheme)
   113  			if tc.admissioncheck != nil {
   114  				builder = builder.WithObjects(tc.admissioncheck)
   115  			}
   116  			if tc.config != nil {
   117  				builder = builder.WithObjects(tc.config)
   118  			}
   119  			client := builder.Build()
   120  			ctx, cancel := context.WithCancel(context.Background())
   121  			defer cancel()
   122  
   123  			helper, err := NewConfigHelper[*kueue.ProvisioningRequestConfig](client)
   124  
   125  			if err != nil {
   126  				t.Fatalf("cannot built the helper: %s", err)
   127  			}
   128  
   129  			gotConfig, gotError := helper.ConfigForAdmissionCheck(ctx, tc.targetAdmissionCheck)
   130  			if diff := cmp.Diff(tc.wantError, gotError, cmpopts.EquateErrors()); diff != "" {
   131  				t.Errorf("unexpected config (-want/+got):\n%s", diff)
   132  			}
   133  			if diff := cmp.Diff(tc.wantConfig, gotConfig, cmpopts.IgnoreFields(kueue.ProvisioningRequestConfig{}, "TypeMeta", "ObjectMeta")); diff != "" {
   134  				t.Errorf("unexpected config (-want/+got):\n%s", diff)
   135  			}
   136  		})
   137  	}
   138  }
   139  
   140  func TestIndexerFunc(t *testing.T) {
   141  	cases := map[string]struct {
   142  		admissioncheck *kueue.AdmissionCheck
   143  		wantResult     []string
   144  	}{
   145  		"nil ac": {},
   146  		"wrong controller": {
   147  			admissioncheck: utiltesting.MakeAdmissionCheck("ac").
   148  				ControllerName("other-controller").
   149  				Parameters(kueue.GroupVersion.Group, "ProvisioningRequestConfig", "config-name").
   150  				Obj(),
   151  		},
   152  		"wrong ref": {
   153  			admissioncheck: utiltesting.MakeAdmissionCheck("ac").
   154  				ControllerName("test-controller").
   155  				Parameters(kueue.GroupVersion.Group, "NotProvisioningRequestConfig", "config-name").
   156  				Obj(),
   157  		},
   158  		"good": {
   159  			admissioncheck: utiltesting.MakeAdmissionCheck("ac").
   160  				ControllerName("test-controller").
   161  				Parameters(kueue.GroupVersion.Group, "ProvisioningRequestConfig", "config-name").
   162  				Obj(),
   163  			wantResult: []string{"config-name"},
   164  		},
   165  	}
   166  
   167  	for name, tc := range cases {
   168  		t.Run(name, func(t *testing.T) {
   169  			scheme := runtime.NewScheme()
   170  			if err := clientgoscheme.AddToScheme(scheme); err != nil {
   171  				panic(err)
   172  			}
   173  			if err := kueue.AddToScheme(scheme); err != nil {
   174  				panic(err)
   175  			}
   176  
   177  			indexFnc := IndexerByConfigFunction("test-controller", kueue.GroupVersion.WithKind("ProvisioningRequestConfig"))
   178  
   179  			gotResult := indexFnc(tc.admissioncheck)
   180  
   181  			if diff := cmp.Diff(tc.wantResult, gotResult); diff != "" {
   182  				t.Errorf("unexpected result (-want/+got):\n%s", diff)
   183  			}
   184  		})
   185  	}
   186  }
   187  
   188  func TestFilterCheckStates(t *testing.T) {
   189  	cases := map[string]struct {
   190  		admissionchecks []kueue.AdmissionCheck
   191  		states          []kueue.AdmissionCheckState
   192  		wantResult      []string
   193  	}{
   194  		"empty": {},
   195  		"no match": {
   196  
   197  			states: []kueue.AdmissionCheckState{
   198  				{Name: "check1"},
   199  				{Name: "check2"},
   200  				{Name: "check3"},
   201  			},
   202  		},
   203  		"two matches": {
   204  			admissionchecks: []kueue.AdmissionCheck{
   205  				*utiltesting.MakeAdmissionCheck("check1").ControllerName("test-controller").Obj(),
   206  				*utiltesting.MakeAdmissionCheck("check2").ControllerName("other-controller").Obj(),
   207  				*utiltesting.MakeAdmissionCheck("check3").ControllerName("test-controller").Obj(),
   208  			},
   209  			states: []kueue.AdmissionCheckState{
   210  				{Name: "check1"},
   211  				{Name: "check2"},
   212  				{Name: "check3"},
   213  			},
   214  			wantResult: []string{"check1", "check3"},
   215  		},
   216  	}
   217  
   218  	for name, tc := range cases {
   219  		t.Run(name, func(t *testing.T) {
   220  			scheme := runtime.NewScheme()
   221  			if err := clientgoscheme.AddToScheme(scheme); err != nil {
   222  				panic(err)
   223  			}
   224  			if err := kueue.AddToScheme(scheme); err != nil {
   225  				panic(err)
   226  			}
   227  			builder := fake.NewClientBuilder().WithScheme(scheme)
   228  			if len(tc.admissionchecks) > 0 {
   229  				builder = builder.WithLists(&kueue.AdmissionCheckList{Items: tc.admissionchecks})
   230  			}
   231  			client := builder.Build()
   232  			ctx, cancel := context.WithCancel(context.Background())
   233  			defer cancel()
   234  
   235  			gotResult, _ := FilterForController(ctx, client, tc.states, "test-controller")
   236  
   237  			if diff := cmp.Diff(tc.wantResult, gotResult); diff != "" {
   238  				t.Errorf("unexpected result (-want/+got):\n%s", diff)
   239  			}
   240  		})
   241  	}
   242  }