sigs.k8s.io/kueue@v0.6.2/cmd/kueue/main_test.go (about)

     1  /*
     2  Copyright 2021 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 main
    18  
    19  import (
    20  	"fmt"
    21  	"os"
    22  	"path/filepath"
    23  	"testing"
    24  
    25  	"github.com/google/go-cmp/cmp"
    26  	"github.com/google/go-cmp/cmp/cmpopts"
    27  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    28  	"k8s.io/utils/ptr"
    29  
    30  	config "sigs.k8s.io/kueue/apis/config/v1beta1"
    31  	"sigs.k8s.io/kueue/pkg/controller/jobs/job"
    32  )
    33  
    34  func TestValidateIntegrationsName(t *testing.T) {
    35  	// temp dir
    36  	tmpDir, err := os.MkdirTemp("", "temp")
    37  	if err != nil {
    38  		t.Fatal(err)
    39  	}
    40  	defer os.RemoveAll(tmpDir)
    41  
    42  	integrationsConfig := filepath.Join(tmpDir, "integrations.yaml")
    43  	if err := os.WriteFile(integrationsConfig, []byte(`
    44  apiVersion: config.kueue.x-k8s.io/v1beta1
    45  kind: Configuration
    46  integrations:
    47    frameworks: 
    48    - batch/job
    49  `), os.FileMode(0600)); err != nil {
    50  		t.Fatal(err)
    51  	}
    52  
    53  	badIntegrationsConfig := filepath.Join(tmpDir, "badIntegrations.yaml")
    54  	if err := os.WriteFile(badIntegrationsConfig, []byte(`
    55  apiVersion: config.kueue.x-k8s.io/v1beta1
    56  kind: Configuration
    57  integrations:
    58    frameworks:
    59    - unregistered/jobframework
    60  `), os.FileMode(0600)); err != nil {
    61  		t.Fatal(err)
    62  	}
    63  
    64  	enableDefaultInternalCertManagement := &config.InternalCertManagement{
    65  		Enable:             ptr.To(true),
    66  		WebhookServiceName: ptr.To(config.DefaultWebhookServiceName),
    67  		WebhookSecretName:  ptr.To(config.DefaultWebhookSecretName),
    68  	}
    69  
    70  	configCmpOpts := []cmp.Option{
    71  		cmpopts.IgnoreFields(config.Configuration{}, "ControllerManager"),
    72  	}
    73  
    74  	defaultClientConnection := &config.ClientConnection{
    75  		QPS:   ptr.To(config.DefaultClientConnectionQPS),
    76  		Burst: ptr.To(config.DefaultClientConnectionBurst),
    77  	}
    78  
    79  	testcases := []struct {
    80  		name              string
    81  		configFile        string
    82  		wantConfiguration config.Configuration
    83  		wantError         error
    84  	}{
    85  		{
    86  			name:       "integrations config",
    87  			configFile: integrationsConfig,
    88  			wantConfiguration: config.Configuration{
    89  				TypeMeta: metav1.TypeMeta{
    90  					APIVersion: config.GroupVersion.String(),
    91  					Kind:       "Configuration",
    92  				},
    93  				Namespace:                  ptr.To(config.DefaultNamespace),
    94  				ManageJobsWithoutQueueName: false,
    95  				InternalCertManagement:     enableDefaultInternalCertManagement,
    96  				ClientConnection:           defaultClientConnection,
    97  				Integrations: &config.Integrations{
    98  					// referencing job.FrameworkName ensures the link of job package
    99  					// therefore the batch/framework should be registered
   100  					Frameworks: []string{job.FrameworkName},
   101  					PodOptions: &config.PodIntegrationOptions{
   102  						NamespaceSelector: &metav1.LabelSelector{
   103  							MatchExpressions: []metav1.LabelSelectorRequirement{
   104  								{
   105  									Key:      "kubernetes.io/metadata.name",
   106  									Operator: metav1.LabelSelectorOpNotIn,
   107  									Values:   []string{"kube-system", "kueue-system"},
   108  								},
   109  							},
   110  						},
   111  						PodSelector: &metav1.LabelSelector{},
   112  					},
   113  				},
   114  				QueueVisibility: &config.QueueVisibility{
   115  					UpdateIntervalSeconds: config.DefaultQueueVisibilityUpdateIntervalSeconds,
   116  					ClusterQueues: &config.ClusterQueueVisibility{
   117  						MaxCount: config.DefaultClusterQueuesMaxCount,
   118  					},
   119  				},
   120  				MultiKueue: &config.MultiKueue{
   121  					GCInterval: &metav1.Duration{Duration: config.DefaultMultiKueueGCInterval},
   122  					Origin:     ptr.To(config.DefaultMultiKueueOrigin),
   123  				},
   124  			},
   125  		},
   126  		{
   127  			name:       "bad integrations config",
   128  			configFile: badIntegrationsConfig,
   129  			wantError:  fmt.Errorf("integrations.frameworks: Unsupported value: \"unregistered/jobframework\": supported values: \"batch/job\", \"jobset.x-k8s.io/jobset\", \"kubeflow.org/mpijob\", \"kubeflow.org/mxjob\", \"kubeflow.org/paddlejob\", \"kubeflow.org/pytorchjob\", \"kubeflow.org/tfjob\", \"kubeflow.org/xgboostjob\", \"pod\", \"ray.io/raycluster\", \"ray.io/rayjob\""),
   130  		},
   131  	}
   132  
   133  	for _, tc := range testcases {
   134  		t.Run(tc.name, func(t *testing.T) {
   135  			_, cfg, err := apply(tc.configFile)
   136  			if tc.wantError == nil {
   137  				if err != nil {
   138  					t.Errorf("Unexpected error:%s", err)
   139  				}
   140  				if diff := cmp.Diff(tc.wantConfiguration, cfg, configCmpOpts...); diff != "" {
   141  					t.Errorf("Unexpected config (-want +got):\n%s", diff)
   142  				}
   143  			} else {
   144  				if diff := cmp.Diff(tc.wantError.Error(), err.Error()); diff != "" {
   145  					t.Errorf("Unexpected error (-want +got):\n%s", diff)
   146  				}
   147  			}
   148  		})
   149  	}
   150  }