sigs.k8s.io/kueue@v0.6.2/pkg/controller/jobs/jobset/jobset_webhook_test.go (about)

     1  /*
     2  Copyright 2022 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 jobset
    18  
    19  import (
    20  	"context"
    21  	"testing"
    22  
    23  	"github.com/google/go-cmp/cmp"
    24  	"k8s.io/apimachinery/pkg/util/validation/field"
    25  	jobset "sigs.k8s.io/jobset/api/jobset/v1alpha2"
    26  
    27  	"sigs.k8s.io/kueue/pkg/controller/constants"
    28  	testingutil "sigs.k8s.io/kueue/pkg/util/testingjobs/jobset"
    29  )
    30  
    31  const (
    32  	invalidRFC1123Message = `a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')`
    33  )
    34  
    35  var (
    36  	labelsPath         = field.NewPath("metadata", "labels")
    37  	queueNameLabelPath = labelsPath.Key(constants.QueueLabel)
    38  )
    39  
    40  func TestValidateCreate(t *testing.T) {
    41  	testcases := []struct {
    42  		name    string
    43  		job     *jobset.JobSet
    44  		wantErr error
    45  	}{
    46  		{
    47  			name:    "simple",
    48  			job:     testingutil.MakeJobSet("job", "default").Queue("queue").Obj(),
    49  			wantErr: nil,
    50  		},
    51  		{
    52  			name:    "invalid queue-name label",
    53  			job:     testingutil.MakeJobSet("job", "default").Queue("queue_name").Obj(),
    54  			wantErr: field.ErrorList{field.Invalid(queueNameLabelPath, "queue_name", invalidRFC1123Message)}.ToAggregate(),
    55  		},
    56  		{
    57  			name:    "with prebuilt workload",
    58  			job:     testingutil.MakeJobSet("job", "default").Queue("queue").Label(constants.PrebuiltWorkloadLabel, "prebuilt-workload").Obj(),
    59  			wantErr: nil,
    60  		},
    61  	}
    62  
    63  	for _, tc := range testcases {
    64  		t.Run(tc.name, func(t *testing.T) {
    65  			jsw := &JobSetWebhook{}
    66  			_, gotErr := jsw.ValidateCreate(context.Background(), tc.job)
    67  
    68  			if diff := cmp.Diff(tc.wantErr, gotErr); diff != "" {
    69  				t.Errorf("validateCreate() mismatch (-want +got):\n%s", diff)
    70  			}
    71  		})
    72  	}
    73  }
    74  
    75  func TestDefault(t *testing.T) {
    76  	testcases := []struct {
    77  		name    string
    78  		job     *jobset.JobSet
    79  		wantJob *jobset.JobSet
    80  	}{
    81  		{
    82  			name: "propagate prebuilt wl name in parent workload annotation",
    83  			job: testingutil.MakeJobSet("job", "default").Queue("queue").
    84  				Label(constants.PrebuiltWorkloadLabel, "prebuilt-workload").
    85  				ReplicatedJobs(
    86  					testingutil.ReplicatedJobRequirements{
    87  						Name:        "rj1",
    88  						Replicas:    1,
    89  						Parallelism: 2,
    90  						Completions: 3,
    91  						Annotations: map[string]string{
    92  							"other-annotation": "val",
    93  						},
    94  					},
    95  					testingutil.ReplicatedJobRequirements{
    96  						Name:        "rj2",
    97  						Replicas:    1,
    98  						Parallelism: 2,
    99  						Completions: 3,
   100  					},
   101  				).
   102  				Obj(),
   103  			wantJob: testingutil.MakeJobSet("job", "default").Queue("queue").
   104  				Label(constants.PrebuiltWorkloadLabel, "prebuilt-workload").
   105  				ReplicatedJobs(
   106  					testingutil.ReplicatedJobRequirements{
   107  						Name:        "rj1",
   108  						Replicas:    1,
   109  						Parallelism: 2,
   110  						Completions: 3,
   111  						Annotations: map[string]string{
   112  							"other-annotation":                 "val",
   113  							constants.ParentWorkloadAnnotation: "prebuilt-workload",
   114  						},
   115  					},
   116  					testingutil.ReplicatedJobRequirements{
   117  						Name:        "rj2",
   118  						Replicas:    1,
   119  						Parallelism: 2,
   120  						Completions: 3,
   121  						Annotations: map[string]string{
   122  							constants.ParentWorkloadAnnotation: "prebuilt-workload",
   123  						},
   124  					},
   125  				).
   126  				Obj(),
   127  		},
   128  	}
   129  
   130  	for _, tc := range testcases {
   131  		t.Run(tc.name, func(t *testing.T) {
   132  			jsw := &JobSetWebhook{}
   133  			gotErr := jsw.Default(context.Background(), tc.job)
   134  
   135  			if gotErr != nil {
   136  				t.Errorf("unexpected Default error: %s", gotErr)
   137  			}
   138  
   139  			if diff := cmp.Diff(tc.wantJob, tc.job); diff != "" {
   140  				t.Errorf("unexpected jobset after Default (-want +got):\n%s", diff)
   141  			}
   142  		})
   143  	}
   144  }