github.com/kubeflow/training-operator@v1.7.0/pkg/controller.v1/control/controller_ref_manager_test.go (about)

     1  // Copyright 2019 The Kubeflow Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package control
    16  
    17  import (
    18  	testutilv1 "github.com/kubeflow/training-operator/test_job/test_util/v1"
    19  	"reflect"
    20  	"testing"
    21  
    22  	"k8s.io/api/core/v1"
    23  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    24  	"k8s.io/apimachinery/pkg/types"
    25  
    26  	testjobv1 "github.com/kubeflow/training-operator/test_job/apis/test_job/v1"
    27  )
    28  
    29  func TestClaimPods(t *testing.T) {
    30  	controllerUID := "123"
    31  
    32  	type test struct {
    33  		name    string
    34  		manager *PodControllerRefManager
    35  		pods    []*v1.Pod
    36  		claimed []*v1.Pod
    37  	}
    38  	var tests = []test{
    39  		func() test {
    40  			testJob := testutilv1.NewTestJob(1)
    41  			testJobLabelSelector, err := metav1.LabelSelectorAsSelector(&metav1.LabelSelector{
    42  				MatchLabels: testutilv1.GenLabels(testJob.Name),
    43  			})
    44  			if err != nil {
    45  				t.Errorf("Unexpected error: %v", err)
    46  			}
    47  			testPod := testutilv1.NewBasePod("pod2", testJob, nil)
    48  			testPod.Labels[testutilv1.LabelGroupName] = "testing"
    49  
    50  			return test{
    51  				name: "Claim pods with correct label",
    52  				manager: NewPodControllerRefManager(&FakePodControl{},
    53  					testJob,
    54  					testJobLabelSelector,
    55  					testjobv1.SchemeGroupVersionKind,
    56  					func() error { return nil }),
    57  				pods:    []*v1.Pod{testutilv1.NewBasePod("pod1", testJob, t), testPod},
    58  				claimed: []*v1.Pod{testutilv1.NewBasePod("pod1", testJob, t)},
    59  			}
    60  		}(),
    61  		func() test {
    62  			controller := testutilv1.NewTestJob(1)
    63  			controllerLabelSelector, err := metav1.LabelSelectorAsSelector(&metav1.LabelSelector{
    64  				MatchLabels: testutilv1.GenLabels(controller.Name),
    65  			})
    66  			if err != nil {
    67  				t.Errorf("Unexpected error: %v", err)
    68  			}
    69  			controller.UID = types.UID(controllerUID)
    70  			now := metav1.Now()
    71  			controller.DeletionTimestamp = &now
    72  			testPod1 := testutilv1.NewBasePod("pod1", controller, t)
    73  			testPod1.SetOwnerReferences([]metav1.OwnerReference{})
    74  			testPod2 := testutilv1.NewBasePod("pod2", controller, t)
    75  			testPod2.SetOwnerReferences([]metav1.OwnerReference{})
    76  			return test{
    77  				name: "Controller marked for deletion can not claim pods",
    78  				manager: NewPodControllerRefManager(&FakePodControl{},
    79  					controller,
    80  					controllerLabelSelector,
    81  					testjobv1.SchemeGroupVersionKind,
    82  					func() error { return nil }),
    83  				pods:    []*v1.Pod{testPod1, testPod2},
    84  				claimed: nil,
    85  			}
    86  		}(),
    87  		func() test {
    88  			controller := testutilv1.NewTestJob(1)
    89  			controllerLabelSelector, err := metav1.LabelSelectorAsSelector(&metav1.LabelSelector{
    90  				MatchLabels: testutilv1.GenLabels(controller.Name),
    91  			})
    92  			if err != nil {
    93  				t.Errorf("Unexpected error: %v", err)
    94  			}
    95  			controller.UID = types.UID(controllerUID)
    96  			now := metav1.Now()
    97  			controller.DeletionTimestamp = &now
    98  			testPod2 := testutilv1.NewBasePod("pod2", controller, t)
    99  			testPod2.SetOwnerReferences([]metav1.OwnerReference{})
   100  			return test{
   101  				name: "Controller marked for deletion can not claim new pods",
   102  				manager: NewPodControllerRefManager(&FakePodControl{},
   103  					controller,
   104  					controllerLabelSelector,
   105  					testjobv1.SchemeGroupVersionKind,
   106  					func() error { return nil }),
   107  				pods:    []*v1.Pod{testutilv1.NewBasePod("pod1", controller, t), testPod2},
   108  				claimed: []*v1.Pod{testutilv1.NewBasePod("pod1", controller, t)},
   109  			}
   110  		}(),
   111  		func() test {
   112  			controller := testutilv1.NewTestJob(1)
   113  			controllerLabelSelector, err := metav1.LabelSelectorAsSelector(&metav1.LabelSelector{
   114  				MatchLabels: testutilv1.GenLabels(controller.Name),
   115  			})
   116  			if err != nil {
   117  				t.Errorf("Unexpected error: %v", err)
   118  			}
   119  			controller2 := testutilv1.NewTestJob(1)
   120  			controller.UID = types.UID(controllerUID)
   121  			controller2.UID = types.UID("AAAAA")
   122  			return test{
   123  				name: "Controller can not claim pods owned by another controller",
   124  				manager: NewPodControllerRefManager(&FakePodControl{},
   125  					controller,
   126  					controllerLabelSelector,
   127  					testjobv1.SchemeGroupVersionKind,
   128  					func() error { return nil }),
   129  				pods:    []*v1.Pod{testutilv1.NewBasePod("pod1", controller, t), testutilv1.NewBasePod("pod2", controller2, t)},
   130  				claimed: []*v1.Pod{testutilv1.NewBasePod("pod1", controller, t)},
   131  			}
   132  		}(),
   133  		func() test {
   134  			controller := testutilv1.NewTestJob(1)
   135  			controllerLabelSelector, err := metav1.LabelSelectorAsSelector(&metav1.LabelSelector{
   136  				MatchLabels: testutilv1.GenLabels(controller.Name),
   137  			})
   138  			if err != nil {
   139  				t.Errorf("Unexpected error: %v", err)
   140  			}
   141  			controller.UID = types.UID(controllerUID)
   142  			testPod2 := testutilv1.NewBasePod("pod2", controller, t)
   143  			testPod2.Labels[testutilv1.LabelGroupName] = "testing"
   144  			return test{
   145  				name: "Controller releases claimed pods when selector doesn't match",
   146  				manager: NewPodControllerRefManager(&FakePodControl{},
   147  					controller,
   148  					controllerLabelSelector,
   149  					testjobv1.SchemeGroupVersionKind,
   150  					func() error { return nil }),
   151  				pods:    []*v1.Pod{testutilv1.NewBasePod("pod1", controller, t), testPod2},
   152  				claimed: []*v1.Pod{testutilv1.NewBasePod("pod1", controller, t)},
   153  			}
   154  		}(),
   155  		func() test {
   156  			controller := testutilv1.NewTestJob(1)
   157  			controllerLabelSelector, err := metav1.LabelSelectorAsSelector(&metav1.LabelSelector{
   158  				MatchLabels: testutilv1.GenLabels(controller.Name),
   159  			})
   160  			if err != nil {
   161  				t.Errorf("Unexpected error: %v", err)
   162  			}
   163  			controller.UID = types.UID(controllerUID)
   164  			testPod1 := testutilv1.NewBasePod("pod1", controller, t)
   165  			testPod2 := testutilv1.NewBasePod("pod2", controller, t)
   166  			testPod2.Labels[testutilv1.LabelGroupName] = "testing"
   167  			now := metav1.Now()
   168  			testPod1.DeletionTimestamp = &now
   169  			testPod2.DeletionTimestamp = &now
   170  
   171  			return test{
   172  				name: "Controller does not claim orphaned pods marked for deletion",
   173  				manager: NewPodControllerRefManager(&FakePodControl{},
   174  					controller,
   175  					controllerLabelSelector,
   176  					testjobv1.SchemeGroupVersionKind,
   177  					func() error { return nil }),
   178  				pods:    []*v1.Pod{testPod1, testPod2},
   179  				claimed: []*v1.Pod{testPod1},
   180  			}
   181  		}(),
   182  	}
   183  	for _, test := range tests {
   184  		claimed, err := test.manager.ClaimPods(test.pods)
   185  		if err != nil {
   186  			t.Errorf("Test case `%s`, unexpected error: %v", test.name, err)
   187  		} else if !reflect.DeepEqual(test.claimed, claimed) {
   188  			t.Errorf("Test case `%s`, claimed wrong pods. Expected %v, got %v", test.name, podToStringSlice(test.claimed), podToStringSlice(claimed))
   189  		}
   190  
   191  	}
   192  }
   193  
   194  func podToStringSlice(pods []*v1.Pod) []string {
   195  	var names []string
   196  	for _, pod := range pods {
   197  		names = append(names, pod.Name)
   198  	}
   199  	return names
   200  }
   201  
   202  func TestClaimServices(t *testing.T) {
   203  	controllerUID := "123"
   204  
   205  	type test struct {
   206  		name     string
   207  		manager  *ServiceControllerRefManager
   208  		services []*v1.Service
   209  		claimed  []*v1.Service
   210  	}
   211  	var tests = []test{
   212  		func() test {
   213  			testJob := testutilv1.NewTestJob(1)
   214  			testJobLabelSelector, err := metav1.LabelSelectorAsSelector(&metav1.LabelSelector{
   215  				MatchLabels: testutilv1.GenLabels(testJob.Name),
   216  			})
   217  			if err != nil {
   218  				t.Errorf("Unexpected error: %v", err)
   219  			}
   220  			testService := testutilv1.NewBaseService("service2", testJob, nil)
   221  			testService.Labels[testutilv1.LabelGroupName] = "testing"
   222  
   223  			return test{
   224  				name: "Claim services with correct label",
   225  				manager: NewServiceControllerRefManager(&FakeServiceControl{},
   226  					testJob,
   227  					testJobLabelSelector,
   228  					testjobv1.SchemeGroupVersionKind,
   229  					func() error { return nil }),
   230  				services: []*v1.Service{testutilv1.NewBaseService("service1", testJob, t), testService},
   231  				claimed:  []*v1.Service{testutilv1.NewBaseService("service1", testJob, t)},
   232  			}
   233  		}(),
   234  		func() test {
   235  			controller := testutilv1.NewTestJob(1)
   236  			controllerLabelSelector, err := metav1.LabelSelectorAsSelector(&metav1.LabelSelector{
   237  				MatchLabels: testutilv1.GenLabels(controller.Name),
   238  			})
   239  			if err != nil {
   240  				t.Errorf("Unexpected error: %v", err)
   241  			}
   242  			controller.UID = types.UID(controllerUID)
   243  			now := metav1.Now()
   244  			controller.DeletionTimestamp = &now
   245  			testService1 := testutilv1.NewBaseService("service1", controller, t)
   246  			testService1.SetOwnerReferences([]metav1.OwnerReference{})
   247  			testService2 := testutilv1.NewBaseService("service2", controller, t)
   248  			testService2.SetOwnerReferences([]metav1.OwnerReference{})
   249  			return test{
   250  				name: "Controller marked for deletion can not claim services",
   251  				manager: NewServiceControllerRefManager(&FakeServiceControl{},
   252  					controller,
   253  					controllerLabelSelector,
   254  					testjobv1.SchemeGroupVersionKind,
   255  					func() error { return nil }),
   256  				services: []*v1.Service{testService1, testService2},
   257  				claimed:  nil,
   258  			}
   259  		}(),
   260  		func() test {
   261  			controller := testutilv1.NewTestJob(1)
   262  			controllerLabelSelector, err := metav1.LabelSelectorAsSelector(&metav1.LabelSelector{
   263  				MatchLabels: testutilv1.GenLabels(controller.Name),
   264  			})
   265  			if err != nil {
   266  				t.Errorf("Unexpected error: %v", err)
   267  			}
   268  			controller.UID = types.UID(controllerUID)
   269  			now := metav1.Now()
   270  			controller.DeletionTimestamp = &now
   271  			testService2 := testutilv1.NewBaseService("service2", controller, t)
   272  			testService2.SetOwnerReferences([]metav1.OwnerReference{})
   273  			return test{
   274  				name: "Controller marked for deletion can not claim new services",
   275  				manager: NewServiceControllerRefManager(&FakeServiceControl{},
   276  					controller,
   277  					controllerLabelSelector,
   278  					testjobv1.SchemeGroupVersionKind,
   279  					func() error { return nil }),
   280  				services: []*v1.Service{testutilv1.NewBaseService("service1", controller, t), testService2},
   281  				claimed:  []*v1.Service{testutilv1.NewBaseService("service1", controller, t)},
   282  			}
   283  		}(),
   284  		func() test {
   285  			controller := testutilv1.NewTestJob(1)
   286  			controllerLabelSelector, err := metav1.LabelSelectorAsSelector(&metav1.LabelSelector{
   287  				MatchLabels: testutilv1.GenLabels(controller.Name),
   288  			})
   289  			if err != nil {
   290  				t.Errorf("Unexpected error: %v", err)
   291  			}
   292  			controller2 := testutilv1.NewTestJob(1)
   293  			controller.UID = types.UID(controllerUID)
   294  			controller2.UID = types.UID("AAAAA")
   295  			return test{
   296  				name: "Controller can not claim services owned by another controller",
   297  				manager: NewServiceControllerRefManager(&FakeServiceControl{},
   298  					controller,
   299  					controllerLabelSelector,
   300  					testjobv1.SchemeGroupVersionKind,
   301  					func() error { return nil }),
   302  				services: []*v1.Service{testutilv1.NewBaseService("service1", controller, t), testutilv1.NewBaseService("service2", controller2, t)},
   303  				claimed:  []*v1.Service{testutilv1.NewBaseService("service1", controller, t)},
   304  			}
   305  		}(),
   306  		func() test {
   307  			controller := testutilv1.NewTestJob(1)
   308  			controllerLabelSelector, err := metav1.LabelSelectorAsSelector(&metav1.LabelSelector{
   309  				MatchLabels: testutilv1.GenLabels(controller.Name),
   310  			})
   311  			if err != nil {
   312  				t.Errorf("Unexpected error: %v", err)
   313  			}
   314  			controller.UID = types.UID(controllerUID)
   315  			testService2 := testutilv1.NewBaseService("service2", controller, t)
   316  			testService2.Labels[testutilv1.LabelGroupName] = "testing"
   317  			return test{
   318  				name: "Controller releases claimed services when selector doesn't match",
   319  				manager: NewServiceControllerRefManager(&FakeServiceControl{},
   320  					controller,
   321  					controllerLabelSelector,
   322  					testjobv1.SchemeGroupVersionKind,
   323  					func() error { return nil }),
   324  				services: []*v1.Service{testutilv1.NewBaseService("service1", controller, t), testService2},
   325  				claimed:  []*v1.Service{testutilv1.NewBaseService("service1", controller, t)},
   326  			}
   327  		}(),
   328  		func() test {
   329  			controller := testutilv1.NewTestJob(1)
   330  			controllerLabelSelector, err := metav1.LabelSelectorAsSelector(&metav1.LabelSelector{
   331  				MatchLabels: testutilv1.GenLabels(controller.Name),
   332  			})
   333  			if err != nil {
   334  				t.Errorf("Unexpected error: %v", err)
   335  			}
   336  			controller.UID = types.UID(controllerUID)
   337  			testService1 := testutilv1.NewBaseService("service1", controller, t)
   338  			testService2 := testutilv1.NewBaseService("service2", controller, t)
   339  			testService2.Labels[testutilv1.LabelGroupName] = "testing"
   340  			now := metav1.Now()
   341  			testService1.DeletionTimestamp = &now
   342  			testService2.DeletionTimestamp = &now
   343  
   344  			return test{
   345  				name: "Controller does not claim orphaned services marked for deletion",
   346  				manager: NewServiceControllerRefManager(&FakeServiceControl{},
   347  					controller,
   348  					controllerLabelSelector,
   349  					testjobv1.SchemeGroupVersionKind,
   350  					func() error { return nil }),
   351  				services: []*v1.Service{testService1, testService2},
   352  				claimed:  []*v1.Service{testService1},
   353  			}
   354  		}(),
   355  	}
   356  	for _, test := range tests {
   357  		claimed, err := test.manager.ClaimServices(test.services)
   358  		if err != nil {
   359  			t.Errorf("Test case `%s`, unexpected error: %v", test.name, err)
   360  		} else if !reflect.DeepEqual(test.claimed, claimed) {
   361  			t.Errorf("Test case `%s`, claimed wrong services. Expected %v, got %v", test.name, serviceToStringSlice(test.claimed), serviceToStringSlice(claimed))
   362  		}
   363  
   364  	}
   365  }
   366  
   367  func serviceToStringSlice(services []*v1.Service) []string {
   368  	var names []string
   369  	for _, service := range services {
   370  		names = append(names, service.Name)
   371  	}
   372  	return names
   373  }