Merge pull request #63661 from xchapter7x/pkg-scheduler

Automatic merge from submit-queue (batch tested with PRs 64285, 63660, 63661, 63662, 64883). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>.

use subtest for table units (pkg/scheduler)

**What this PR does / why we need it**: Update scheduler's unit table tests to use subtest

**Which issue(s) this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when PR gets merged)*:

**Special notes for your reviewer**:
breaks up PR: https://github.com/kubernetes/kubernetes/pull/63281
/ref #63267

**Release note**:

```release-note
This PR will leverage subtests on the existing table tests for the scheduler units.
Some refactoring of error/status messages and functions to align with new approach.

```
This commit is contained in:
Kubernetes Submit Queue 2018-06-21 01:19:22 -07:00 committed by GitHub
commit 58574021a7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -145,6 +145,7 @@ func TestScheduler(t *testing.T) {
testNode := v1.Node{ObjectMeta: metav1.ObjectMeta{Name: "machine1", UID: types.UID("machine1")}} testNode := v1.Node{ObjectMeta: metav1.ObjectMeta{Name: "machine1", UID: types.UID("machine1")}}
table := []struct { table := []struct {
name string
injectBindError error injectBindError error
sendPod *v1.Pod sendPod *v1.Pod
algo algorithm.ScheduleAlgorithm algo algorithm.ScheduleAlgorithm
@ -156,18 +157,23 @@ func TestScheduler(t *testing.T) {
eventReason string eventReason string
}{ }{
{ {
name: "bind assumed pod scheduled",
sendPod: podWithID("foo", ""), sendPod: podWithID("foo", ""),
algo: mockScheduler{testNode.Name, nil}, algo: mockScheduler{testNode.Name, nil},
expectBind: &v1.Binding{ObjectMeta: metav1.ObjectMeta{Name: "foo", UID: types.UID("foo")}, Target: v1.ObjectReference{Kind: "Node", Name: testNode.Name}}, expectBind: &v1.Binding{ObjectMeta: metav1.ObjectMeta{Name: "foo", UID: types.UID("foo")}, Target: v1.ObjectReference{Kind: "Node", Name: testNode.Name}},
expectAssumedPod: podWithID("foo", testNode.Name), expectAssumedPod: podWithID("foo", testNode.Name),
eventReason: "Scheduled", eventReason: "Scheduled",
}, { },
{
name: "error pod failed scheduling",
sendPod: podWithID("foo", ""), sendPod: podWithID("foo", ""),
algo: mockScheduler{testNode.Name, errS}, algo: mockScheduler{testNode.Name, errS},
expectError: errS, expectError: errS,
expectErrorPod: podWithID("foo", ""), expectErrorPod: podWithID("foo", ""),
eventReason: "FailedScheduling", eventReason: "FailedScheduling",
}, { },
{
name: "error bind forget pod failed scheduling",
sendPod: podWithID("foo", ""), sendPod: podWithID("foo", ""),
algo: mockScheduler{testNode.Name, nil}, algo: mockScheduler{testNode.Name, nil},
expectBind: &v1.Binding{ObjectMeta: metav1.ObjectMeta{Name: "foo", UID: types.UID("foo")}, Target: v1.ObjectReference{Kind: "Node", Name: testNode.Name}}, expectBind: &v1.Binding{ObjectMeta: metav1.ObjectMeta{Name: "foo", UID: types.UID("foo")}, Target: v1.ObjectReference{Kind: "Node", Name: testNode.Name}},
@ -184,7 +190,8 @@ func TestScheduler(t *testing.T) {
}, },
} }
for i, item := range table { for _, item := range table {
t.Run(item.name, func(t *testing.T) {
var gotError error var gotError error
var gotPod *v1.Pod var gotPod *v1.Pod
var gotForgetPod *v1.Pod var gotForgetPod *v1.Pod
@ -227,28 +234,29 @@ func TestScheduler(t *testing.T) {
called := make(chan struct{}) called := make(chan struct{})
events := eventBroadcaster.StartEventWatcher(func(e *v1.Event) { events := eventBroadcaster.StartEventWatcher(func(e *v1.Event) {
if e, a := item.eventReason, e.Reason; e != a { if e, a := item.eventReason, e.Reason; e != a {
t.Errorf("%v: expected %v, got %v", i, e, a) t.Errorf("expected %v, got %v", e, a)
} }
close(called) close(called)
}) })
s.scheduleOne() s.scheduleOne()
<-called <-called
if e, a := item.expectAssumedPod, gotAssumedPod; !reflect.DeepEqual(e, a) { if e, a := item.expectAssumedPod, gotAssumedPod; !reflect.DeepEqual(e, a) {
t.Errorf("%v: assumed pod: wanted %v, got %v", i, e, a) t.Errorf("assumed pod: wanted %v, got %v", e, a)
} }
if e, a := item.expectErrorPod, gotPod; !reflect.DeepEqual(e, a) { if e, a := item.expectErrorPod, gotPod; !reflect.DeepEqual(e, a) {
t.Errorf("%v: error pod: wanted %v, got %v", i, e, a) t.Errorf("error pod: wanted %v, got %v", e, a)
} }
if e, a := item.expectForgetPod, gotForgetPod; !reflect.DeepEqual(e, a) { if e, a := item.expectForgetPod, gotForgetPod; !reflect.DeepEqual(e, a) {
t.Errorf("%v: forget pod: wanted %v, got %v", i, e, a) t.Errorf("forget pod: wanted %v, got %v", e, a)
} }
if e, a := item.expectError, gotError; !reflect.DeepEqual(e, a) { if e, a := item.expectError, gotError; !reflect.DeepEqual(e, a) {
t.Errorf("%v: error: wanted %v, got %v", i, e, a) t.Errorf("error: wanted %v, got %v", e, a)
} }
if e, a := item.expectBind, gotBinding; !reflect.DeepEqual(e, a) { if e, a := item.expectBind, gotBinding; !reflect.DeepEqual(e, a) {
t.Errorf("%v: error: %s", i, diff.ObjectDiff(e, a)) t.Errorf("error: %s", diff.ObjectDiff(e, a))
} }
events.Stop() events.Stop()
})
} }
} }
@ -381,21 +389,25 @@ func TestSchedulerErrorWithLongBinding(t *testing.T) {
conflictPod := podWithPort("bar", "", 8080) conflictPod := podWithPort("bar", "", 8080)
pods := map[string]*v1.Pod{firstPod.Name: firstPod, conflictPod.Name: conflictPod} pods := map[string]*v1.Pod{firstPod.Name: firstPod, conflictPod.Name: conflictPod}
for _, test := range []struct { for _, test := range []struct {
name string
Expected map[string]bool Expected map[string]bool
CacheTTL time.Duration CacheTTL time.Duration
BindingDuration time.Duration BindingDuration time.Duration
}{ }{
{ {
name: "long cache ttl",
Expected: map[string]bool{firstPod.Name: true}, Expected: map[string]bool{firstPod.Name: true},
CacheTTL: 100 * time.Millisecond, CacheTTL: 100 * time.Millisecond,
BindingDuration: 300 * time.Millisecond, BindingDuration: 300 * time.Millisecond,
}, },
{ {
name: "short cache ttl",
Expected: map[string]bool{firstPod.Name: true}, Expected: map[string]bool{firstPod.Name: true},
CacheTTL: 10 * time.Second, CacheTTL: 10 * time.Second,
BindingDuration: 300 * time.Millisecond, BindingDuration: 300 * time.Millisecond,
}, },
} { } {
t.Run(test.name, func(t *testing.T) {
queuedPodStore := clientcache.NewFIFO(clientcache.MetaNamespaceKeyFunc) queuedPodStore := clientcache.NewFIFO(clientcache.MetaNamespaceKeyFunc)
scache := schedulercache.New(test.CacheTTL, stop) scache := schedulercache.New(test.CacheTTL, stop)
@ -427,6 +439,7 @@ func TestSchedulerErrorWithLongBinding(t *testing.T) {
if !reflect.DeepEqual(resultBindings, test.Expected) { if !reflect.DeepEqual(resultBindings, test.Expected) {
t.Errorf("Result binding are not equal to expected. %v != %v", resultBindings, test.Expected) t.Errorf("Result binding are not equal to expected. %v != %v", resultBindings, test.Expected)
} }
})
} }
} }
@ -673,7 +686,8 @@ func TestSchedulerWithVolumeBinding(t *testing.T) {
utilfeature.DefaultFeatureGate.Set("VolumeScheduling=true") utilfeature.DefaultFeatureGate.Set("VolumeScheduling=true")
defer utilfeature.DefaultFeatureGate.Set("VolumeScheduling=false") defer utilfeature.DefaultFeatureGate.Set("VolumeScheduling=false")
table := map[string]struct { table := []struct {
name string
expectError error expectError error
expectPodBind *v1.Binding expectPodBind *v1.Binding
expectAssumeCalled bool expectAssumeCalled bool
@ -681,7 +695,8 @@ func TestSchedulerWithVolumeBinding(t *testing.T) {
eventReason string eventReason string
volumeBinderConfig *persistentvolume.FakeVolumeBinderConfig volumeBinderConfig *persistentvolume.FakeVolumeBinderConfig
}{ }{
"all-bound": { {
name: "all bound",
volumeBinderConfig: &persistentvolume.FakeVolumeBinderConfig{ volumeBinderConfig: &persistentvolume.FakeVolumeBinderConfig{
AllBound: true, AllBound: true,
FindUnboundSatsified: true, FindUnboundSatsified: true,
@ -692,7 +707,8 @@ func TestSchedulerWithVolumeBinding(t *testing.T) {
eventReason: "Scheduled", eventReason: "Scheduled",
}, },
"bound,invalid-pv-affinity": { {
name: "bound/invalid pv affinity",
volumeBinderConfig: &persistentvolume.FakeVolumeBinderConfig{ volumeBinderConfig: &persistentvolume.FakeVolumeBinderConfig{
AllBound: true, AllBound: true,
FindUnboundSatsified: true, FindUnboundSatsified: true,
@ -701,7 +717,8 @@ func TestSchedulerWithVolumeBinding(t *testing.T) {
eventReason: "FailedScheduling", eventReason: "FailedScheduling",
expectError: makePredicateError("1 node(s) had volume node affinity conflict"), expectError: makePredicateError("1 node(s) had volume node affinity conflict"),
}, },
"unbound,no-matches": { {
name: "unbound/no matches",
volumeBinderConfig: &persistentvolume.FakeVolumeBinderConfig{ volumeBinderConfig: &persistentvolume.FakeVolumeBinderConfig{
FindUnboundSatsified: false, FindUnboundSatsified: false,
FindBoundSatsified: true, FindBoundSatsified: true,
@ -709,7 +726,8 @@ func TestSchedulerWithVolumeBinding(t *testing.T) {
eventReason: "FailedScheduling", eventReason: "FailedScheduling",
expectError: makePredicateError("1 node(s) didn't find available persistent volumes to bind"), expectError: makePredicateError("1 node(s) didn't find available persistent volumes to bind"),
}, },
"bound-and-unbound-unsatisfied": { {
name: "bound and unbound unsatisfied",
volumeBinderConfig: &persistentvolume.FakeVolumeBinderConfig{ volumeBinderConfig: &persistentvolume.FakeVolumeBinderConfig{
FindUnboundSatsified: false, FindUnboundSatsified: false,
FindBoundSatsified: false, FindBoundSatsified: false,
@ -717,7 +735,8 @@ func TestSchedulerWithVolumeBinding(t *testing.T) {
eventReason: "FailedScheduling", eventReason: "FailedScheduling",
expectError: makePredicateError("1 node(s) didn't find available persistent volumes to bind, 1 node(s) had volume node affinity conflict"), expectError: makePredicateError("1 node(s) didn't find available persistent volumes to bind, 1 node(s) had volume node affinity conflict"),
}, },
"unbound,found-matches": { {
name: "unbound/found matches",
volumeBinderConfig: &persistentvolume.FakeVolumeBinderConfig{ volumeBinderConfig: &persistentvolume.FakeVolumeBinderConfig{
FindUnboundSatsified: true, FindUnboundSatsified: true,
FindBoundSatsified: true, FindBoundSatsified: true,
@ -728,7 +747,8 @@ func TestSchedulerWithVolumeBinding(t *testing.T) {
eventReason: "FailedScheduling", eventReason: "FailedScheduling",
expectError: fmt.Errorf("Volume binding started, waiting for completion"), expectError: fmt.Errorf("Volume binding started, waiting for completion"),
}, },
"unbound,found-matches,already-bound": { {
name: "unbound/found matches/already-bound",
volumeBinderConfig: &persistentvolume.FakeVolumeBinderConfig{ volumeBinderConfig: &persistentvolume.FakeVolumeBinderConfig{
FindUnboundSatsified: true, FindUnboundSatsified: true,
FindBoundSatsified: true, FindBoundSatsified: true,
@ -739,14 +759,16 @@ func TestSchedulerWithVolumeBinding(t *testing.T) {
eventReason: "FailedScheduling", eventReason: "FailedScheduling",
expectError: fmt.Errorf("Volume binding started, waiting for completion"), expectError: fmt.Errorf("Volume binding started, waiting for completion"),
}, },
"predicate-error": { {
name: "predicate error",
volumeBinderConfig: &persistentvolume.FakeVolumeBinderConfig{ volumeBinderConfig: &persistentvolume.FakeVolumeBinderConfig{
FindErr: findErr, FindErr: findErr,
}, },
eventReason: "FailedScheduling", eventReason: "FailedScheduling",
expectError: findErr, expectError: findErr,
}, },
"assume-error": { {
name: "assume error",
volumeBinderConfig: &persistentvolume.FakeVolumeBinderConfig{ volumeBinderConfig: &persistentvolume.FakeVolumeBinderConfig{
FindUnboundSatsified: true, FindUnboundSatsified: true,
FindBoundSatsified: true, FindBoundSatsified: true,
@ -756,7 +778,8 @@ func TestSchedulerWithVolumeBinding(t *testing.T) {
eventReason: "FailedScheduling", eventReason: "FailedScheduling",
expectError: assumeErr, expectError: assumeErr,
}, },
"bind-error": { {
name: "bind error",
volumeBinderConfig: &persistentvolume.FakeVolumeBinderConfig{ volumeBinderConfig: &persistentvolume.FakeVolumeBinderConfig{
FindUnboundSatsified: true, FindUnboundSatsified: true,
FindBoundSatsified: true, FindBoundSatsified: true,
@ -770,7 +793,8 @@ func TestSchedulerWithVolumeBinding(t *testing.T) {
}, },
} }
for name, item := range table { for _, item := range table {
t.Run(item.name, func(t *testing.T) {
stop := make(chan struct{}) stop := make(chan struct{})
fakeVolumeBinder := volumebinder.NewFakeVolumeBinder(item.volumeBinderConfig) fakeVolumeBinder := volumebinder.NewFakeVolumeBinder(item.volumeBinderConfig)
internalBinder, ok := fakeVolumeBinder.Binder.(*persistentvolume.FakeVolumeBinder) internalBinder, ok := fakeVolumeBinder.Binder.(*persistentvolume.FakeVolumeBinder)
@ -782,7 +806,7 @@ func TestSchedulerWithVolumeBinding(t *testing.T) {
eventChan := make(chan struct{}) eventChan := make(chan struct{})
events := eventBroadcaster.StartEventWatcher(func(e *v1.Event) { events := eventBroadcaster.StartEventWatcher(func(e *v1.Event) {
if e, a := item.eventReason, e.Reason; e != a { if e, a := item.eventReason, e.Reason; e != a {
t.Errorf("%v: expected %v, got %v", name, e, a) t.Errorf("expected %v, got %v", e, a)
} }
close(eventChan) close(eventChan)
}) })
@ -795,7 +819,7 @@ func TestSchedulerWithVolumeBinding(t *testing.T) {
select { select {
case <-eventChan: case <-eventChan:
case <-time.After(wait.ForeverTestTimeout): case <-time.After(wait.ForeverTestTimeout):
t.Fatalf("%v: scheduling timeout after %v", name, wait.ForeverTestTimeout) t.Fatalf("scheduling timeout after %v", wait.ForeverTestTimeout)
} }
events.Stop() events.Stop()
@ -804,11 +828,11 @@ func TestSchedulerWithVolumeBinding(t *testing.T) {
select { select {
case err := <-errChan: case err := <-errChan:
if item.expectError == nil || !reflect.DeepEqual(item.expectError.Error(), err.Error()) { if item.expectError == nil || !reflect.DeepEqual(item.expectError.Error(), err.Error()) {
t.Errorf("%v: \n err \nWANT=%+v,\nGOT=%+v", name, item.expectError, err) t.Errorf("err \nWANT=%+v,\nGOT=%+v", item.expectError, err)
} }
case <-time.After(chanTimeout): case <-time.After(chanTimeout):
if item.expectError != nil { if item.expectError != nil {
t.Errorf("%v: did not receive error after %v", name, chanTimeout) t.Errorf("did not receive error after %v", chanTimeout)
} }
} }
@ -816,22 +840,23 @@ func TestSchedulerWithVolumeBinding(t *testing.T) {
select { select {
case b := <-bindingChan: case b := <-bindingChan:
if !reflect.DeepEqual(item.expectPodBind, b) { if !reflect.DeepEqual(item.expectPodBind, b) {
t.Errorf("%v: \n err \nWANT=%+v,\nGOT=%+v", name, item.expectPodBind, b) t.Errorf("err \nWANT=%+v,\nGOT=%+v", item.expectPodBind, b)
} }
case <-time.After(chanTimeout): case <-time.After(chanTimeout):
if item.expectPodBind != nil { if item.expectPodBind != nil {
t.Errorf("%v: did not receive pod binding after %v", name, chanTimeout) t.Errorf("did not receive pod binding after %v", chanTimeout)
} }
} }
if item.expectAssumeCalled != internalBinder.AssumeCalled { if item.expectAssumeCalled != internalBinder.AssumeCalled {
t.Errorf("%v: expectedAssumeCall %v", name, item.expectAssumeCalled) t.Errorf("expectedAssumeCall %v", item.expectAssumeCalled)
} }
if item.expectBindCalled != internalBinder.BindCalled { if item.expectBindCalled != internalBinder.BindCalled {
t.Errorf("%v: expectedBindCall %v", name, item.expectBindCalled) t.Errorf("expectedBindCall %v", item.expectBindCalled)
} }
close(stop) close(stop)
})
} }
} }