mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-03 01:06:27 +00:00
Job: Use ControllerRef to route watch events.
This is part of the completion of ControllerRef, as described here: https://github.com/kubernetes/community/blob/master/contributors/design-proposals/controller-ref.md#watches
This commit is contained in:
parent
424de52779
commit
067a8ff3c2
@ -144,18 +144,22 @@ func (jm *JobController) Run(workers int, stopCh <-chan struct{}) {
|
|||||||
<-stopCh
|
<-stopCh
|
||||||
}
|
}
|
||||||
|
|
||||||
// getPodJob returns the job managing the given pod.
|
// getPodJobs returns a list of Jobs that potentially match a Pod.
|
||||||
func (jm *JobController) getPodJob(pod *v1.Pod) *batch.Job {
|
func (jm *JobController) getPodJobs(pod *v1.Pod) []*batch.Job {
|
||||||
jobs, err := jm.jobLister.GetPodJobs(pod)
|
jobs, err := jm.jobLister.GetPodJobs(pod)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.V(4).Infof("No jobs found for pod %v, job controller will avoid syncing", pod.Name)
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if len(jobs) > 1 {
|
if len(jobs) > 1 {
|
||||||
|
// ControllerRef will ensure we don't do anything crazy, but more than one
|
||||||
|
// item in this list nevertheless constitutes user error.
|
||||||
utilruntime.HandleError(fmt.Errorf("user error! more than one job is selecting pods with labels: %+v", pod.Labels))
|
utilruntime.HandleError(fmt.Errorf("user error! more than one job is selecting pods with labels: %+v", pod.Labels))
|
||||||
sort.Sort(byCreationTimestamp(jobs))
|
|
||||||
}
|
}
|
||||||
return &jobs[0]
|
ret := make([]*batch.Job, 0, len(jobs))
|
||||||
|
for i := range jobs {
|
||||||
|
ret = append(ret, &jobs[i])
|
||||||
|
}
|
||||||
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
// When a pod is created, enqueue the controller that manages it and update it's expectations.
|
// When a pod is created, enqueue the controller that manages it and update it's expectations.
|
||||||
@ -167,14 +171,32 @@ func (jm *JobController) addPod(obj interface{}) {
|
|||||||
jm.deletePod(pod)
|
jm.deletePod(pod)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if job := jm.getPodJob(pod); job != nil {
|
|
||||||
|
// If it has a ControllerRef, that's all that matters.
|
||||||
|
if controllerRef := controller.GetControllerOf(pod); controllerRef != nil {
|
||||||
|
if controllerRef.Kind != controllerKind.Kind {
|
||||||
|
// It's controlled by a different type of controller.
|
||||||
|
return
|
||||||
|
}
|
||||||
|
job, err := jm.jobLister.Jobs(pod.Namespace).Get(controllerRef.Name)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
jobKey, err := controller.KeyFunc(job)
|
jobKey, err := controller.KeyFunc(job)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utilruntime.HandleError(fmt.Errorf("Couldn't get key for job %#v: %v", job, err))
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
jm.expectations.CreationObserved(jobKey)
|
jm.expectations.CreationObserved(jobKey)
|
||||||
jm.enqueueController(job)
|
jm.enqueueController(job)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, it's an orphan. Get a list of all matching controllers and sync
|
||||||
|
// them to see if anyone wants to adopt it.
|
||||||
|
// DO NOT observe creation because no controller should be waiting for an
|
||||||
|
// orphan.
|
||||||
|
for _, job := range jm.getPodJobs(pod) {
|
||||||
|
jm.enqueueController(job)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,15 +219,40 @@ func (jm *JobController) updatePod(old, cur interface{}) {
|
|||||||
jm.deletePod(curPod)
|
jm.deletePod(curPod)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if job := jm.getPodJob(curPod); job != nil {
|
|
||||||
jm.enqueueController(job)
|
labelChanged := !reflect.DeepEqual(curPod.Labels, oldPod.Labels)
|
||||||
|
|
||||||
|
curControllerRef := controller.GetControllerOf(curPod)
|
||||||
|
oldControllerRef := controller.GetControllerOf(oldPod)
|
||||||
|
controllerRefChanged := !reflect.DeepEqual(curControllerRef, oldControllerRef)
|
||||||
|
if controllerRefChanged &&
|
||||||
|
oldControllerRef != nil && oldControllerRef.Kind == controllerKind.Kind {
|
||||||
|
// The ControllerRef was changed. Sync the old controller, if any.
|
||||||
|
job, err := jm.jobLister.Jobs(oldPod.Namespace).Get(oldControllerRef.Name)
|
||||||
|
if err == nil {
|
||||||
|
jm.enqueueController(job)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Only need to get the old job if the labels changed.
|
|
||||||
if !reflect.DeepEqual(curPod.Labels, oldPod.Labels) {
|
// If it has a ControllerRef, that's all that matters.
|
||||||
// If the old and new job are the same, the first one that syncs
|
if curControllerRef != nil {
|
||||||
// will set expectations preventing any damage from the second.
|
if curControllerRef.Kind != controllerKind.Kind {
|
||||||
if oldJob := jm.getPodJob(oldPod); oldJob != nil {
|
// It's controlled by a different type of controller.
|
||||||
jm.enqueueController(oldJob)
|
return
|
||||||
|
}
|
||||||
|
job, err := jm.jobLister.Jobs(curPod.Namespace).Get(curControllerRef.Name)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
jm.enqueueController(job)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, it's an orphan. If anything changed, sync matching controllers
|
||||||
|
// to see if anyone wants to adopt it now.
|
||||||
|
if labelChanged || controllerRefChanged {
|
||||||
|
for _, job := range jm.getPodJobs(curPod) {
|
||||||
|
jm.enqueueController(job)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -222,24 +269,36 @@ func (jm *JobController) deletePod(obj interface{}) {
|
|||||||
if !ok {
|
if !ok {
|
||||||
tombstone, ok := obj.(cache.DeletedFinalStateUnknown)
|
tombstone, ok := obj.(cache.DeletedFinalStateUnknown)
|
||||||
if !ok {
|
if !ok {
|
||||||
utilruntime.HandleError(fmt.Errorf("Couldn't get object from tombstone %+v", obj))
|
utilruntime.HandleError(fmt.Errorf("couldn't get object from tombstone %+v", obj))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
pod, ok = tombstone.Obj.(*v1.Pod)
|
pod, ok = tombstone.Obj.(*v1.Pod)
|
||||||
if !ok {
|
if !ok {
|
||||||
utilruntime.HandleError(fmt.Errorf("Tombstone contained object that is not a pod %+v", obj))
|
utilruntime.HandleError(fmt.Errorf("tombstone contained object that is not a pod %+v", obj))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if job := jm.getPodJob(pod); job != nil {
|
|
||||||
jobKey, err := controller.KeyFunc(job)
|
controllerRef := controller.GetControllerOf(pod)
|
||||||
if err != nil {
|
if controllerRef == nil {
|
||||||
utilruntime.HandleError(fmt.Errorf("Couldn't get key for job %#v: %v", job, err))
|
// No controller should care about orphans being deleted.
|
||||||
return
|
return
|
||||||
}
|
|
||||||
jm.expectations.DeletionObserved(jobKey)
|
|
||||||
jm.enqueueController(job)
|
|
||||||
}
|
}
|
||||||
|
if controllerRef.Kind != controllerKind.Kind {
|
||||||
|
// It's controlled by a different type of controller.
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
job, err := jm.jobLister.Jobs(pod.Namespace).Get(controllerRef.Name)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
jobKey, err := controller.KeyFunc(job)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
jm.expectations.DeletionObserved(jobKey)
|
||||||
|
jm.enqueueController(job)
|
||||||
}
|
}
|
||||||
|
|
||||||
// obj could be an *batch.Job, or a DeletionFinalStateUnknown marker item.
|
// obj could be an *batch.Job, or a DeletionFinalStateUnknown marker item.
|
||||||
|
@ -18,6 +18,7 @@ package job
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -598,7 +599,11 @@ func TestJobPodLookup(t *testing.T) {
|
|||||||
}
|
}
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
sharedInformerFactory.Batch().V1().Jobs().Informer().GetIndexer().Add(tc.job)
|
sharedInformerFactory.Batch().V1().Jobs().Informer().GetIndexer().Add(tc.job)
|
||||||
if job := manager.getPodJob(tc.pod); job != nil {
|
if jobs := manager.getPodJobs(tc.pod); len(jobs) > 0 {
|
||||||
|
if got, want := len(jobs), 1; got != want {
|
||||||
|
t.Errorf("len(jobs) = %v, want %v", got, want)
|
||||||
|
}
|
||||||
|
job := jobs[0]
|
||||||
if tc.expectedName != job.Name {
|
if tc.expectedName != job.Name {
|
||||||
t.Errorf("Got job %+v expected %+v", job.Name, tc.expectedName)
|
t.Errorf("Got job %+v expected %+v", job.Name, tc.expectedName)
|
||||||
}
|
}
|
||||||
@ -720,6 +725,279 @@ func TestGetPodsForJobRelease(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAddPod(t *testing.T) {
|
||||||
|
clientset := clientset.NewForConfigOrDie(&restclient.Config{Host: "", ContentConfig: restclient.ContentConfig{GroupVersion: &api.Registry.GroupOrDie(v1.GroupName).GroupVersion}})
|
||||||
|
jm, informer := newJobControllerFromClient(clientset, controller.NoResyncPeriodFunc)
|
||||||
|
jm.podStoreSynced = alwaysReady
|
||||||
|
jm.jobStoreSynced = alwaysReady
|
||||||
|
|
||||||
|
job1 := newJob(1, 1)
|
||||||
|
job1.Name = "job1"
|
||||||
|
job2 := newJob(1, 1)
|
||||||
|
job2.Name = "job2"
|
||||||
|
informer.Batch().V1().Jobs().Informer().GetIndexer().Add(job1)
|
||||||
|
informer.Batch().V1().Jobs().Informer().GetIndexer().Add(job2)
|
||||||
|
|
||||||
|
pod1 := newPod("pod1", job1)
|
||||||
|
pod2 := newPod("pod2", job2)
|
||||||
|
informer.Core().V1().Pods().Informer().GetIndexer().Add(pod1)
|
||||||
|
informer.Core().V1().Pods().Informer().GetIndexer().Add(pod2)
|
||||||
|
|
||||||
|
jm.addPod(pod1)
|
||||||
|
if got, want := jm.queue.Len(), 1; got != want {
|
||||||
|
t.Fatalf("queue.Len() = %v, want %v", got, want)
|
||||||
|
}
|
||||||
|
key, done := jm.queue.Get()
|
||||||
|
if key == nil || done {
|
||||||
|
t.Fatalf("failed to enqueue controller for pod %v", pod1.Name)
|
||||||
|
}
|
||||||
|
expectedKey, _ := controller.KeyFunc(job1)
|
||||||
|
if got, want := key.(string), expectedKey; got != want {
|
||||||
|
t.Errorf("queue.Get() = %v, want %v", got, want)
|
||||||
|
}
|
||||||
|
|
||||||
|
jm.addPod(pod2)
|
||||||
|
if got, want := jm.queue.Len(), 1; got != want {
|
||||||
|
t.Fatalf("queue.Len() = %v, want %v", got, want)
|
||||||
|
}
|
||||||
|
key, done = jm.queue.Get()
|
||||||
|
if key == nil || done {
|
||||||
|
t.Fatalf("failed to enqueue controller for pod %v", pod2.Name)
|
||||||
|
}
|
||||||
|
expectedKey, _ = controller.KeyFunc(job2)
|
||||||
|
if got, want := key.(string), expectedKey; got != want {
|
||||||
|
t.Errorf("queue.Get() = %v, want %v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAddPodOrphan(t *testing.T) {
|
||||||
|
clientset := clientset.NewForConfigOrDie(&restclient.Config{Host: "", ContentConfig: restclient.ContentConfig{GroupVersion: &api.Registry.GroupOrDie(v1.GroupName).GroupVersion}})
|
||||||
|
jm, informer := newJobControllerFromClient(clientset, controller.NoResyncPeriodFunc)
|
||||||
|
jm.podStoreSynced = alwaysReady
|
||||||
|
jm.jobStoreSynced = alwaysReady
|
||||||
|
|
||||||
|
job1 := newJob(1, 1)
|
||||||
|
job1.Name = "job1"
|
||||||
|
job2 := newJob(1, 1)
|
||||||
|
job2.Name = "job2"
|
||||||
|
job3 := newJob(1, 1)
|
||||||
|
job3.Name = "job3"
|
||||||
|
job3.Spec.Selector.MatchLabels = map[string]string{"other": "labels"}
|
||||||
|
informer.Batch().V1().Jobs().Informer().GetIndexer().Add(job1)
|
||||||
|
informer.Batch().V1().Jobs().Informer().GetIndexer().Add(job2)
|
||||||
|
informer.Batch().V1().Jobs().Informer().GetIndexer().Add(job3)
|
||||||
|
|
||||||
|
pod1 := newPod("pod1", job1)
|
||||||
|
// Make pod an orphan. Expect all matching controllers to be queued.
|
||||||
|
pod1.OwnerReferences = nil
|
||||||
|
informer.Core().V1().Pods().Informer().GetIndexer().Add(pod1)
|
||||||
|
|
||||||
|
jm.addPod(pod1)
|
||||||
|
if got, want := jm.queue.Len(), 2; got != want {
|
||||||
|
t.Fatalf("queue.Len() = %v, want %v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUpdatePod(t *testing.T) {
|
||||||
|
clientset := clientset.NewForConfigOrDie(&restclient.Config{Host: "", ContentConfig: restclient.ContentConfig{GroupVersion: &api.Registry.GroupOrDie(v1.GroupName).GroupVersion}})
|
||||||
|
jm, informer := newJobControllerFromClient(clientset, controller.NoResyncPeriodFunc)
|
||||||
|
jm.podStoreSynced = alwaysReady
|
||||||
|
jm.jobStoreSynced = alwaysReady
|
||||||
|
|
||||||
|
job1 := newJob(1, 1)
|
||||||
|
job1.Name = "job1"
|
||||||
|
job2 := newJob(1, 1)
|
||||||
|
job2.Name = "job2"
|
||||||
|
informer.Batch().V1().Jobs().Informer().GetIndexer().Add(job1)
|
||||||
|
informer.Batch().V1().Jobs().Informer().GetIndexer().Add(job2)
|
||||||
|
|
||||||
|
pod1 := newPod("pod1", job1)
|
||||||
|
pod2 := newPod("pod2", job2)
|
||||||
|
informer.Core().V1().Pods().Informer().GetIndexer().Add(pod1)
|
||||||
|
informer.Core().V1().Pods().Informer().GetIndexer().Add(pod2)
|
||||||
|
|
||||||
|
prev := *pod1
|
||||||
|
bumpResourceVersion(pod1)
|
||||||
|
jm.updatePod(&prev, pod1)
|
||||||
|
if got, want := jm.queue.Len(), 1; got != want {
|
||||||
|
t.Fatalf("queue.Len() = %v, want %v", got, want)
|
||||||
|
}
|
||||||
|
key, done := jm.queue.Get()
|
||||||
|
if key == nil || done {
|
||||||
|
t.Fatalf("failed to enqueue controller for pod %v", pod1.Name)
|
||||||
|
}
|
||||||
|
expectedKey, _ := controller.KeyFunc(job1)
|
||||||
|
if got, want := key.(string), expectedKey; got != want {
|
||||||
|
t.Errorf("queue.Get() = %v, want %v", got, want)
|
||||||
|
}
|
||||||
|
|
||||||
|
prev = *pod2
|
||||||
|
bumpResourceVersion(pod2)
|
||||||
|
jm.updatePod(&prev, pod2)
|
||||||
|
if got, want := jm.queue.Len(), 1; got != want {
|
||||||
|
t.Fatalf("queue.Len() = %v, want %v", got, want)
|
||||||
|
}
|
||||||
|
key, done = jm.queue.Get()
|
||||||
|
if key == nil || done {
|
||||||
|
t.Fatalf("failed to enqueue controller for pod %v", pod2.Name)
|
||||||
|
}
|
||||||
|
expectedKey, _ = controller.KeyFunc(job2)
|
||||||
|
if got, want := key.(string), expectedKey; got != want {
|
||||||
|
t.Errorf("queue.Get() = %v, want %v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUpdatePodOrphanWithNewLabels(t *testing.T) {
|
||||||
|
clientset := clientset.NewForConfigOrDie(&restclient.Config{Host: "", ContentConfig: restclient.ContentConfig{GroupVersion: &api.Registry.GroupOrDie(v1.GroupName).GroupVersion}})
|
||||||
|
jm, informer := newJobControllerFromClient(clientset, controller.NoResyncPeriodFunc)
|
||||||
|
jm.podStoreSynced = alwaysReady
|
||||||
|
jm.jobStoreSynced = alwaysReady
|
||||||
|
|
||||||
|
job1 := newJob(1, 1)
|
||||||
|
job1.Name = "job1"
|
||||||
|
job2 := newJob(1, 1)
|
||||||
|
job2.Name = "job2"
|
||||||
|
informer.Batch().V1().Jobs().Informer().GetIndexer().Add(job1)
|
||||||
|
informer.Batch().V1().Jobs().Informer().GetIndexer().Add(job2)
|
||||||
|
|
||||||
|
pod1 := newPod("pod1", job1)
|
||||||
|
pod1.OwnerReferences = nil
|
||||||
|
informer.Core().V1().Pods().Informer().GetIndexer().Add(pod1)
|
||||||
|
|
||||||
|
// Labels changed on orphan. Expect newly matching controllers to queue.
|
||||||
|
prev := *pod1
|
||||||
|
prev.Labels = map[string]string{"foo2": "bar2"}
|
||||||
|
bumpResourceVersion(pod1)
|
||||||
|
jm.updatePod(&prev, pod1)
|
||||||
|
if got, want := jm.queue.Len(), 2; got != want {
|
||||||
|
t.Fatalf("queue.Len() = %v, want %v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUpdatePodChangeControllerRef(t *testing.T) {
|
||||||
|
clientset := clientset.NewForConfigOrDie(&restclient.Config{Host: "", ContentConfig: restclient.ContentConfig{GroupVersion: &api.Registry.GroupOrDie(v1.GroupName).GroupVersion}})
|
||||||
|
jm, informer := newJobControllerFromClient(clientset, controller.NoResyncPeriodFunc)
|
||||||
|
jm.podStoreSynced = alwaysReady
|
||||||
|
jm.jobStoreSynced = alwaysReady
|
||||||
|
|
||||||
|
job1 := newJob(1, 1)
|
||||||
|
job1.Name = "job1"
|
||||||
|
job2 := newJob(1, 1)
|
||||||
|
job2.Name = "job2"
|
||||||
|
informer.Batch().V1().Jobs().Informer().GetIndexer().Add(job1)
|
||||||
|
informer.Batch().V1().Jobs().Informer().GetIndexer().Add(job2)
|
||||||
|
|
||||||
|
pod1 := newPod("pod1", job1)
|
||||||
|
informer.Core().V1().Pods().Informer().GetIndexer().Add(pod1)
|
||||||
|
|
||||||
|
// Changed ControllerRef. Expect both old and new to queue.
|
||||||
|
prev := *pod1
|
||||||
|
prev.OwnerReferences = []metav1.OwnerReference{*newControllerRef(job2)}
|
||||||
|
bumpResourceVersion(pod1)
|
||||||
|
jm.updatePod(&prev, pod1)
|
||||||
|
if got, want := jm.queue.Len(), 2; got != want {
|
||||||
|
t.Fatalf("queue.Len() = %v, want %v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUpdatePodRelease(t *testing.T) {
|
||||||
|
clientset := clientset.NewForConfigOrDie(&restclient.Config{Host: "", ContentConfig: restclient.ContentConfig{GroupVersion: &api.Registry.GroupOrDie(v1.GroupName).GroupVersion}})
|
||||||
|
jm, informer := newJobControllerFromClient(clientset, controller.NoResyncPeriodFunc)
|
||||||
|
jm.podStoreSynced = alwaysReady
|
||||||
|
jm.jobStoreSynced = alwaysReady
|
||||||
|
|
||||||
|
job1 := newJob(1, 1)
|
||||||
|
job1.Name = "job1"
|
||||||
|
job2 := newJob(1, 1)
|
||||||
|
job2.Name = "job2"
|
||||||
|
informer.Batch().V1().Jobs().Informer().GetIndexer().Add(job1)
|
||||||
|
informer.Batch().V1().Jobs().Informer().GetIndexer().Add(job2)
|
||||||
|
|
||||||
|
pod1 := newPod("pod1", job1)
|
||||||
|
informer.Core().V1().Pods().Informer().GetIndexer().Add(pod1)
|
||||||
|
|
||||||
|
// Remove ControllerRef. Expect all matching to queue for adoption.
|
||||||
|
prev := *pod1
|
||||||
|
pod1.OwnerReferences = nil
|
||||||
|
bumpResourceVersion(pod1)
|
||||||
|
jm.updatePod(&prev, pod1)
|
||||||
|
if got, want := jm.queue.Len(), 2; got != want {
|
||||||
|
t.Fatalf("queue.Len() = %v, want %v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDeletePod(t *testing.T) {
|
||||||
|
clientset := clientset.NewForConfigOrDie(&restclient.Config{Host: "", ContentConfig: restclient.ContentConfig{GroupVersion: &api.Registry.GroupOrDie(v1.GroupName).GroupVersion}})
|
||||||
|
jm, informer := newJobControllerFromClient(clientset, controller.NoResyncPeriodFunc)
|
||||||
|
jm.podStoreSynced = alwaysReady
|
||||||
|
jm.jobStoreSynced = alwaysReady
|
||||||
|
|
||||||
|
job1 := newJob(1, 1)
|
||||||
|
job1.Name = "job1"
|
||||||
|
job2 := newJob(1, 1)
|
||||||
|
job2.Name = "job2"
|
||||||
|
informer.Batch().V1().Jobs().Informer().GetIndexer().Add(job1)
|
||||||
|
informer.Batch().V1().Jobs().Informer().GetIndexer().Add(job2)
|
||||||
|
|
||||||
|
pod1 := newPod("pod1", job1)
|
||||||
|
pod2 := newPod("pod2", job2)
|
||||||
|
informer.Core().V1().Pods().Informer().GetIndexer().Add(pod1)
|
||||||
|
informer.Core().V1().Pods().Informer().GetIndexer().Add(pod2)
|
||||||
|
|
||||||
|
jm.deletePod(pod1)
|
||||||
|
if got, want := jm.queue.Len(), 1; got != want {
|
||||||
|
t.Fatalf("queue.Len() = %v, want %v", got, want)
|
||||||
|
}
|
||||||
|
key, done := jm.queue.Get()
|
||||||
|
if key == nil || done {
|
||||||
|
t.Fatalf("failed to enqueue controller for pod %v", pod1.Name)
|
||||||
|
}
|
||||||
|
expectedKey, _ := controller.KeyFunc(job1)
|
||||||
|
if got, want := key.(string), expectedKey; got != want {
|
||||||
|
t.Errorf("queue.Get() = %v, want %v", got, want)
|
||||||
|
}
|
||||||
|
|
||||||
|
jm.deletePod(pod2)
|
||||||
|
if got, want := jm.queue.Len(), 1; got != want {
|
||||||
|
t.Fatalf("queue.Len() = %v, want %v", got, want)
|
||||||
|
}
|
||||||
|
key, done = jm.queue.Get()
|
||||||
|
if key == nil || done {
|
||||||
|
t.Fatalf("failed to enqueue controller for pod %v", pod2.Name)
|
||||||
|
}
|
||||||
|
expectedKey, _ = controller.KeyFunc(job2)
|
||||||
|
if got, want := key.(string), expectedKey; got != want {
|
||||||
|
t.Errorf("queue.Get() = %v, want %v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDeletePodOrphan(t *testing.T) {
|
||||||
|
clientset := clientset.NewForConfigOrDie(&restclient.Config{Host: "", ContentConfig: restclient.ContentConfig{GroupVersion: &api.Registry.GroupOrDie(v1.GroupName).GroupVersion}})
|
||||||
|
jm, informer := newJobControllerFromClient(clientset, controller.NoResyncPeriodFunc)
|
||||||
|
jm.podStoreSynced = alwaysReady
|
||||||
|
jm.jobStoreSynced = alwaysReady
|
||||||
|
|
||||||
|
job1 := newJob(1, 1)
|
||||||
|
job1.Name = "job1"
|
||||||
|
job2 := newJob(1, 1)
|
||||||
|
job2.Name = "job2"
|
||||||
|
job3 := newJob(1, 1)
|
||||||
|
job3.Name = "job3"
|
||||||
|
job3.Spec.Selector.MatchLabels = map[string]string{"other": "labels"}
|
||||||
|
informer.Batch().V1().Jobs().Informer().GetIndexer().Add(job1)
|
||||||
|
informer.Batch().V1().Jobs().Informer().GetIndexer().Add(job2)
|
||||||
|
informer.Batch().V1().Jobs().Informer().GetIndexer().Add(job3)
|
||||||
|
|
||||||
|
pod1 := newPod("pod1", job1)
|
||||||
|
pod1.OwnerReferences = nil
|
||||||
|
informer.Core().V1().Pods().Informer().GetIndexer().Add(pod1)
|
||||||
|
|
||||||
|
jm.deletePod(pod1)
|
||||||
|
if got, want := jm.queue.Len(), 0; got != want {
|
||||||
|
t.Fatalf("queue.Len() = %v, want %v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type FakeJobExpectations struct {
|
type FakeJobExpectations struct {
|
||||||
*controller.ControllerExpectations
|
*controller.ControllerExpectations
|
||||||
satisfied bool
|
satisfied bool
|
||||||
@ -855,3 +1133,8 @@ func TestWatchPods(t *testing.T) {
|
|||||||
t.Log("Waiting for pod to reach syncHandler")
|
t.Log("Waiting for pod to reach syncHandler")
|
||||||
<-received
|
<-received
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func bumpResourceVersion(obj metav1.Object) {
|
||||||
|
ver, _ := strconv.ParseInt(obj.GetResourceVersion(), 10, 32)
|
||||||
|
obj.SetResourceVersion(strconv.FormatInt(ver+1, 10))
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user