mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-10 04:27:54 +00:00
Merge pull request #117113 from pohly/test-integration-race-detection-scheduler
test/integration/scheduler: fix data races
This commit is contained in:
commit
3ac21a5a30
@ -14,13 +14,15 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// Package plugins contains functional tests for scheduler plugin support.
|
||||||
|
// Beware that the plugins in this directory are not meant to be used in
|
||||||
|
// performance tests because they don't behave like real plugins.
|
||||||
package plugins
|
package plugins
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -65,7 +67,7 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type PreEnqueuePlugin struct {
|
type PreEnqueuePlugin struct {
|
||||||
called int32
|
called int
|
||||||
admit bool
|
admit bool
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,23 +78,62 @@ type PreFilterPlugin struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ScorePlugin struct {
|
type ScorePlugin struct {
|
||||||
|
mutex sync.Mutex
|
||||||
failScore bool
|
failScore bool
|
||||||
numScoreCalled int32
|
numScoreCalled int
|
||||||
highScoreNode string
|
highScoreNode string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (sp *ScorePlugin) deepCopy() *ScorePlugin {
|
||||||
|
sp.mutex.Lock()
|
||||||
|
defer sp.mutex.Unlock()
|
||||||
|
|
||||||
|
return &ScorePlugin{
|
||||||
|
failScore: sp.failScore,
|
||||||
|
numScoreCalled: sp.numScoreCalled,
|
||||||
|
highScoreNode: sp.highScoreNode,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type ScoreWithNormalizePlugin struct {
|
type ScoreWithNormalizePlugin struct {
|
||||||
|
mutex sync.Mutex
|
||||||
numScoreCalled int
|
numScoreCalled int
|
||||||
numNormalizeScoreCalled int
|
numNormalizeScoreCalled int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (sp *ScoreWithNormalizePlugin) deepCopy() *ScoreWithNormalizePlugin {
|
||||||
|
sp.mutex.Lock()
|
||||||
|
defer sp.mutex.Unlock()
|
||||||
|
|
||||||
|
return &ScoreWithNormalizePlugin{
|
||||||
|
numScoreCalled: sp.numScoreCalled,
|
||||||
|
numNormalizeScoreCalled: sp.numNormalizeScoreCalled,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type FilterPlugin struct {
|
type FilterPlugin struct {
|
||||||
numFilterCalled int32
|
mutex sync.Mutex
|
||||||
|
numFilterCalled int
|
||||||
failFilter bool
|
failFilter bool
|
||||||
rejectFilter bool
|
rejectFilter bool
|
||||||
|
|
||||||
numCalledPerPod map[string]int
|
numCalledPerPod map[string]int
|
||||||
sync.RWMutex
|
}
|
||||||
|
|
||||||
|
func (fp *FilterPlugin) deepCopy() *FilterPlugin {
|
||||||
|
fp.mutex.Lock()
|
||||||
|
defer fp.mutex.Unlock()
|
||||||
|
|
||||||
|
clone := &FilterPlugin{
|
||||||
|
numFilterCalled: fp.numFilterCalled,
|
||||||
|
failFilter: fp.failFilter,
|
||||||
|
rejectFilter: fp.rejectFilter,
|
||||||
|
numCalledPerPod: make(map[string]int),
|
||||||
|
}
|
||||||
|
for pod, counter := range fp.numCalledPerPod {
|
||||||
|
clone.numCalledPerPod[pod] = counter
|
||||||
|
}
|
||||||
|
return clone
|
||||||
}
|
}
|
||||||
|
|
||||||
type PostFilterPlugin struct {
|
type PostFilterPlugin struct {
|
||||||
@ -118,6 +159,7 @@ type PreScorePlugin struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type PreBindPlugin struct {
|
type PreBindPlugin struct {
|
||||||
|
mutex sync.Mutex
|
||||||
numPreBindCalled int
|
numPreBindCalled int
|
||||||
failPreBind bool
|
failPreBind bool
|
||||||
rejectPreBind bool
|
rejectPreBind bool
|
||||||
@ -127,7 +169,34 @@ type PreBindPlugin struct {
|
|||||||
podUIDs map[types.UID]struct{}
|
podUIDs map[types.UID]struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (pp *PreBindPlugin) set(fail, reject, succeed bool) {
|
||||||
|
pp.mutex.Lock()
|
||||||
|
defer pp.mutex.Unlock()
|
||||||
|
|
||||||
|
pp.failPreBind = fail
|
||||||
|
pp.rejectPreBind = reject
|
||||||
|
pp.succeedOnRetry = succeed
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pp *PreBindPlugin) deepCopy() *PreBindPlugin {
|
||||||
|
pp.mutex.Lock()
|
||||||
|
defer pp.mutex.Unlock()
|
||||||
|
|
||||||
|
clone := &PreBindPlugin{
|
||||||
|
numPreBindCalled: pp.numPreBindCalled,
|
||||||
|
failPreBind: pp.failPreBind,
|
||||||
|
rejectPreBind: pp.rejectPreBind,
|
||||||
|
succeedOnRetry: pp.succeedOnRetry,
|
||||||
|
podUIDs: make(map[types.UID]struct{}),
|
||||||
|
}
|
||||||
|
for uid := range pp.podUIDs {
|
||||||
|
clone.podUIDs[uid] = struct{}{}
|
||||||
|
}
|
||||||
|
return clone
|
||||||
|
}
|
||||||
|
|
||||||
type BindPlugin struct {
|
type BindPlugin struct {
|
||||||
|
mutex sync.Mutex
|
||||||
name string
|
name string
|
||||||
numBindCalled int
|
numBindCalled int
|
||||||
bindStatus *framework.Status
|
bindStatus *framework.Status
|
||||||
@ -135,13 +204,39 @@ type BindPlugin struct {
|
|||||||
pluginInvokeEventChan chan pluginInvokeEvent
|
pluginInvokeEventChan chan pluginInvokeEvent
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (bp *BindPlugin) deepCopy() *BindPlugin {
|
||||||
|
bp.mutex.Lock()
|
||||||
|
defer bp.mutex.Unlock()
|
||||||
|
|
||||||
|
return &BindPlugin{
|
||||||
|
name: bp.name,
|
||||||
|
numBindCalled: bp.numBindCalled,
|
||||||
|
bindStatus: bp.bindStatus,
|
||||||
|
client: bp.client,
|
||||||
|
pluginInvokeEventChan: bp.pluginInvokeEventChan,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type PostBindPlugin struct {
|
type PostBindPlugin struct {
|
||||||
|
mutex sync.Mutex
|
||||||
name string
|
name string
|
||||||
numPostBindCalled int
|
numPostBindCalled int
|
||||||
pluginInvokeEventChan chan pluginInvokeEvent
|
pluginInvokeEventChan chan pluginInvokeEvent
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (pp *PostBindPlugin) deepCopy() *PostBindPlugin {
|
||||||
|
pp.mutex.Lock()
|
||||||
|
defer pp.mutex.Unlock()
|
||||||
|
|
||||||
|
return &PostBindPlugin{
|
||||||
|
name: pp.name,
|
||||||
|
numPostBindCalled: pp.numPostBindCalled,
|
||||||
|
pluginInvokeEventChan: pp.pluginInvokeEventChan,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type PermitPlugin struct {
|
type PermitPlugin struct {
|
||||||
|
mutex sync.Mutex
|
||||||
name string
|
name string
|
||||||
numPermitCalled int
|
numPermitCalled int
|
||||||
failPermit bool
|
failPermit bool
|
||||||
@ -156,6 +251,26 @@ type PermitPlugin struct {
|
|||||||
fh framework.Handle
|
fh framework.Handle
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (pp *PermitPlugin) deepCopy() *PermitPlugin {
|
||||||
|
pp.mutex.Lock()
|
||||||
|
defer pp.mutex.Unlock()
|
||||||
|
|
||||||
|
return &PermitPlugin{
|
||||||
|
name: pp.name,
|
||||||
|
numPermitCalled: pp.numPermitCalled,
|
||||||
|
failPermit: pp.failPermit,
|
||||||
|
rejectPermit: pp.rejectPermit,
|
||||||
|
timeoutPermit: pp.timeoutPermit,
|
||||||
|
waitAndRejectPermit: pp.waitAndRejectPermit,
|
||||||
|
waitAndAllowPermit: pp.waitAndAllowPermit,
|
||||||
|
cancelled: pp.cancelled,
|
||||||
|
waitingPod: pp.waitingPod,
|
||||||
|
rejectingPod: pp.rejectingPod,
|
||||||
|
allowingPod: pp.allowingPod,
|
||||||
|
fh: pp.fh,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
enqueuePluginName = "enqueue-plugin"
|
enqueuePluginName = "enqueue-plugin"
|
||||||
prefilterPluginName = "prefilter-plugin"
|
prefilterPluginName = "prefilter-plugin"
|
||||||
@ -216,13 +331,16 @@ func (sp *ScorePlugin) Name() string {
|
|||||||
|
|
||||||
// Score returns the score of scheduling a pod on a specific node.
|
// Score returns the score of scheduling a pod on a specific node.
|
||||||
func (sp *ScorePlugin) Score(ctx context.Context, state *framework.CycleState, p *v1.Pod, nodeName string) (int64, *framework.Status) {
|
func (sp *ScorePlugin) Score(ctx context.Context, state *framework.CycleState, p *v1.Pod, nodeName string) (int64, *framework.Status) {
|
||||||
curCalled := atomic.AddInt32(&sp.numScoreCalled, 1)
|
sp.mutex.Lock()
|
||||||
|
defer sp.mutex.Unlock()
|
||||||
|
|
||||||
|
sp.numScoreCalled++
|
||||||
if sp.failScore {
|
if sp.failScore {
|
||||||
return 0, framework.NewStatus(framework.Error, fmt.Sprintf("injecting failure for pod %v", p.Name))
|
return 0, framework.NewStatus(framework.Error, fmt.Sprintf("injecting failure for pod %v", p.Name))
|
||||||
}
|
}
|
||||||
|
|
||||||
score := int64(1)
|
score := int64(1)
|
||||||
if curCalled == 1 {
|
if sp.numScoreCalled == 1 {
|
||||||
// The first node is scored the highest, the rest is scored lower.
|
// The first node is scored the highest, the rest is scored lower.
|
||||||
sp.highScoreNode = nodeName
|
sp.highScoreNode = nodeName
|
||||||
score = framework.MaxNodeScore
|
score = framework.MaxNodeScore
|
||||||
@ -241,6 +359,9 @@ func (sp *ScoreWithNormalizePlugin) Name() string {
|
|||||||
|
|
||||||
// Score returns the score of scheduling a pod on a specific node.
|
// Score returns the score of scheduling a pod on a specific node.
|
||||||
func (sp *ScoreWithNormalizePlugin) Score(ctx context.Context, state *framework.CycleState, p *v1.Pod, nodeName string) (int64, *framework.Status) {
|
func (sp *ScoreWithNormalizePlugin) Score(ctx context.Context, state *framework.CycleState, p *v1.Pod, nodeName string) (int64, *framework.Status) {
|
||||||
|
sp.mutex.Lock()
|
||||||
|
defer sp.mutex.Unlock()
|
||||||
|
|
||||||
sp.numScoreCalled++
|
sp.numScoreCalled++
|
||||||
score := int64(10)
|
score := int64(10)
|
||||||
return score, nil
|
return score, nil
|
||||||
@ -263,12 +384,12 @@ func (fp *FilterPlugin) Name() string {
|
|||||||
// Filter is a test function that returns an error or nil, depending on the
|
// Filter is a test function that returns an error or nil, depending on the
|
||||||
// value of "failFilter".
|
// value of "failFilter".
|
||||||
func (fp *FilterPlugin) Filter(ctx context.Context, state *framework.CycleState, pod *v1.Pod, nodeInfo *framework.NodeInfo) *framework.Status {
|
func (fp *FilterPlugin) Filter(ctx context.Context, state *framework.CycleState, pod *v1.Pod, nodeInfo *framework.NodeInfo) *framework.Status {
|
||||||
atomic.AddInt32(&fp.numFilterCalled, 1)
|
fp.mutex.Lock()
|
||||||
|
defer fp.mutex.Unlock()
|
||||||
|
|
||||||
|
fp.numFilterCalled++
|
||||||
if fp.numCalledPerPod != nil {
|
if fp.numCalledPerPod != nil {
|
||||||
fp.Lock()
|
|
||||||
fp.numCalledPerPod[fmt.Sprintf("%v/%v", pod.Namespace, pod.Name)]++
|
fp.numCalledPerPod[fmt.Sprintf("%v/%v", pod.Namespace, pod.Name)]++
|
||||||
fp.Unlock()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if fp.failFilter {
|
if fp.failFilter {
|
||||||
@ -328,6 +449,9 @@ func (pp *PreBindPlugin) Name() string {
|
|||||||
|
|
||||||
// PreBind is a test function that returns (true, nil) or errors for testing.
|
// PreBind is a test function that returns (true, nil) or errors for testing.
|
||||||
func (pp *PreBindPlugin) PreBind(ctx context.Context, state *framework.CycleState, pod *v1.Pod, nodeName string) *framework.Status {
|
func (pp *PreBindPlugin) PreBind(ctx context.Context, state *framework.CycleState, pod *v1.Pod, nodeName string) *framework.Status {
|
||||||
|
pp.mutex.Lock()
|
||||||
|
defer pp.mutex.Unlock()
|
||||||
|
|
||||||
pp.numPreBindCalled++
|
pp.numPreBindCalled++
|
||||||
if _, tried := pp.podUIDs[pod.UID]; tried && pp.succeedOnRetry {
|
if _, tried := pp.podUIDs[pod.UID]; tried && pp.succeedOnRetry {
|
||||||
return nil
|
return nil
|
||||||
@ -349,6 +473,9 @@ func (bp *BindPlugin) Name() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (bp *BindPlugin) Bind(ctx context.Context, state *framework.CycleState, p *v1.Pod, nodeName string) *framework.Status {
|
func (bp *BindPlugin) Bind(ctx context.Context, state *framework.CycleState, p *v1.Pod, nodeName string) *framework.Status {
|
||||||
|
bp.mutex.Lock()
|
||||||
|
defer bp.mutex.Unlock()
|
||||||
|
|
||||||
bp.numBindCalled++
|
bp.numBindCalled++
|
||||||
if bp.pluginInvokeEventChan != nil {
|
if bp.pluginInvokeEventChan != nil {
|
||||||
bp.pluginInvokeEventChan <- pluginInvokeEvent{pluginName: bp.Name(), val: bp.numBindCalled}
|
bp.pluginInvokeEventChan <- pluginInvokeEvent{pluginName: bp.Name(), val: bp.numBindCalled}
|
||||||
@ -374,6 +501,9 @@ func (pp *PostBindPlugin) Name() string {
|
|||||||
|
|
||||||
// PostBind is a test function, which counts the number of times called.
|
// PostBind is a test function, which counts the number of times called.
|
||||||
func (pp *PostBindPlugin) PostBind(ctx context.Context, state *framework.CycleState, pod *v1.Pod, nodeName string) {
|
func (pp *PostBindPlugin) PostBind(ctx context.Context, state *framework.CycleState, pod *v1.Pod, nodeName string) {
|
||||||
|
pp.mutex.Lock()
|
||||||
|
defer pp.mutex.Unlock()
|
||||||
|
|
||||||
pp.numPostBindCalled++
|
pp.numPostBindCalled++
|
||||||
if pp.pluginInvokeEventChan != nil {
|
if pp.pluginInvokeEventChan != nil {
|
||||||
pp.pluginInvokeEventChan <- pluginInvokeEvent{pluginName: pp.Name(), val: pp.numPostBindCalled}
|
pp.pluginInvokeEventChan <- pluginInvokeEvent{pluginName: pp.Name(), val: pp.numPostBindCalled}
|
||||||
@ -443,6 +573,9 @@ func (pp *PermitPlugin) Name() string {
|
|||||||
|
|
||||||
// Permit implements the permit test plugin.
|
// Permit implements the permit test plugin.
|
||||||
func (pp *PermitPlugin) Permit(ctx context.Context, state *framework.CycleState, pod *v1.Pod, nodeName string) (*framework.Status, time.Duration) {
|
func (pp *PermitPlugin) Permit(ctx context.Context, state *framework.CycleState, pod *v1.Pod, nodeName string) (*framework.Status, time.Duration) {
|
||||||
|
pp.mutex.Lock()
|
||||||
|
defer pp.mutex.Unlock()
|
||||||
|
|
||||||
pp.numPermitCalled++
|
pp.numPermitCalled++
|
||||||
if pp.failPermit {
|
if pp.failPermit {
|
||||||
return framework.NewStatus(framework.Error, fmt.Sprintf("injecting failure for pod %v", pod.Name)), 0
|
return framework.NewStatus(framework.Error, fmt.Sprintf("injecting failure for pod %v", pod.Name)), 0
|
||||||
@ -454,6 +587,8 @@ func (pp *PermitPlugin) Permit(ctx context.Context, state *framework.CycleState,
|
|||||||
go func() {
|
go func() {
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
|
pp.mutex.Lock()
|
||||||
|
defer pp.mutex.Unlock()
|
||||||
pp.cancelled = true
|
pp.cancelled = true
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
@ -487,6 +622,8 @@ func (pp *PermitPlugin) allowAllPods() {
|
|||||||
|
|
||||||
// rejectAllPods rejects all waiting pods.
|
// rejectAllPods rejects all waiting pods.
|
||||||
func (pp *PermitPlugin) rejectAllPods() {
|
func (pp *PermitPlugin) rejectAllPods() {
|
||||||
|
pp.mutex.Lock()
|
||||||
|
defer pp.mutex.Unlock()
|
||||||
pp.fh.IterateOverWaitingPods(func(wp framework.WaitingPod) { wp.Reject(pp.name, "rejectAllPods") })
|
pp.fh.IterateOverWaitingPods(func(wp framework.WaitingPod) { wp.Reject(pp.name, "rejectAllPods") })
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -559,18 +696,18 @@ func TestPreFilterPlugin(t *testing.T) {
|
|||||||
|
|
||||||
// TestPostFilterPlugin tests invocation of postFilter plugins.
|
// TestPostFilterPlugin tests invocation of postFilter plugins.
|
||||||
func TestPostFilterPlugin(t *testing.T) {
|
func TestPostFilterPlugin(t *testing.T) {
|
||||||
var numNodes int32 = 1
|
numNodes := 1
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
numNodes int32
|
numNodes int
|
||||||
rejectFilter bool
|
rejectFilter bool
|
||||||
failScore bool
|
failScore bool
|
||||||
rejectPostFilter bool
|
rejectPostFilter bool
|
||||||
rejectPostFilter2 bool
|
rejectPostFilter2 bool
|
||||||
breakPostFilter bool
|
breakPostFilter bool
|
||||||
breakPostFilter2 bool
|
breakPostFilter2 bool
|
||||||
expectFilterNumCalled int32
|
expectFilterNumCalled int
|
||||||
expectScoreNumCalled int32
|
expectScoreNumCalled int
|
||||||
expectPostFilterNumCalled int
|
expectPostFilterNumCalled int
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
@ -712,20 +849,20 @@ func TestPostFilterPlugin(t *testing.T) {
|
|||||||
t.Errorf("Didn't expect the pod to be scheduled.")
|
t.Errorf("Didn't expect the pod to be scheduled.")
|
||||||
}
|
}
|
||||||
|
|
||||||
if numFilterCalled := atomic.LoadInt32(&filterPlugin.numFilterCalled); numFilterCalled < tt.expectFilterNumCalled {
|
if numFilterCalled := filterPlugin.deepCopy().numFilterCalled; numFilterCalled < tt.expectFilterNumCalled {
|
||||||
t.Errorf("Expected the filter plugin to be called at least %v times, but got %v.", tt.expectFilterNumCalled, numFilterCalled)
|
t.Errorf("Expected the filter plugin to be called at least %v times, but got %v.", tt.expectFilterNumCalled, numFilterCalled)
|
||||||
}
|
}
|
||||||
if numScoreCalled := atomic.LoadInt32(&scorePlugin.numScoreCalled); numScoreCalled < tt.expectScoreNumCalled {
|
if numScoreCalled := scorePlugin.deepCopy().numScoreCalled; numScoreCalled < tt.expectScoreNumCalled {
|
||||||
t.Errorf("Expected the score plugin to be called at least %v times, but got %v.", tt.expectScoreNumCalled, numScoreCalled)
|
t.Errorf("Expected the score plugin to be called at least %v times, but got %v.", tt.expectScoreNumCalled, numScoreCalled)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if err = testutils.WaitForPodToSchedule(testCtx.ClientSet, pod); err != nil {
|
if err = testutils.WaitForPodToSchedule(testCtx.ClientSet, pod); err != nil {
|
||||||
t.Errorf("Expected the pod to be scheduled. error: %v", err)
|
t.Errorf("Expected the pod to be scheduled. error: %v", err)
|
||||||
}
|
}
|
||||||
if numFilterCalled := atomic.LoadInt32(&filterPlugin.numFilterCalled); numFilterCalled != tt.expectFilterNumCalled {
|
if numFilterCalled := filterPlugin.deepCopy().numFilterCalled; numFilterCalled != tt.expectFilterNumCalled {
|
||||||
t.Errorf("Expected the filter plugin to be called %v times, but got %v.", tt.expectFilterNumCalled, numFilterCalled)
|
t.Errorf("Expected the filter plugin to be called %v times, but got %v.", tt.expectFilterNumCalled, numFilterCalled)
|
||||||
}
|
}
|
||||||
if numScoreCalled := atomic.LoadInt32(&scorePlugin.numScoreCalled); numScoreCalled != tt.expectScoreNumCalled {
|
if numScoreCalled := scorePlugin.deepCopy().numScoreCalled; numScoreCalled != tt.expectScoreNumCalled {
|
||||||
t.Errorf("Expected the score plugin to be called %v times, but got %v.", tt.expectScoreNumCalled, numScoreCalled)
|
t.Errorf("Expected the score plugin to be called %v times, but got %v.", tt.expectScoreNumCalled, numScoreCalled)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -792,7 +929,7 @@ func TestScorePlugin(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if numScoreCalled := atomic.LoadInt32(&scorePlugin.numScoreCalled); numScoreCalled == 0 {
|
if numScoreCalled := scorePlugin.deepCopy().numScoreCalled; numScoreCalled == 0 {
|
||||||
t.Errorf("Expected the score plugin to be called.")
|
t.Errorf("Expected the score plugin to be called.")
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -820,10 +957,11 @@ func TestNormalizeScorePlugin(t *testing.T) {
|
|||||||
t.Errorf("Expected the pod to be scheduled. error: %v", err)
|
t.Errorf("Expected the pod to be scheduled. error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if scoreWithNormalizePlugin.numScoreCalled == 0 {
|
p := scoreWithNormalizePlugin.deepCopy()
|
||||||
|
if p.numScoreCalled == 0 {
|
||||||
t.Errorf("Expected the score plugin to be called.")
|
t.Errorf("Expected the score plugin to be called.")
|
||||||
}
|
}
|
||||||
if scoreWithNormalizePlugin.numNormalizeScoreCalled == 0 {
|
if p.numNormalizeScoreCalled == 0 {
|
||||||
t.Error("Expected the normalize score plugin to be called")
|
t.Error("Expected the normalize score plugin to be called")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -980,9 +1118,8 @@ func TestPrebindPlugin(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
preBindPlugin.failPreBind = test.fail
|
preBindPlugin.set(test.fail, test.reject, test.succeedOnRetry)
|
||||||
preBindPlugin.rejectPreBind = test.reject
|
|
||||||
preBindPlugin.succeedOnRetry = test.succeedOnRetry
|
|
||||||
// Create a best effort pod.
|
// Create a best effort pod.
|
||||||
pod, err := createPausePod(testCtx.ClientSet,
|
pod, err := createPausePod(testCtx.ClientSet,
|
||||||
initPausePod(&testutils.PausePodConfig{Name: "test-pod", Namespace: testCtx.NS.Name}))
|
initPausePod(&testutils.PausePodConfig{Name: "test-pod", Namespace: testCtx.NS.Name}))
|
||||||
@ -1006,7 +1143,8 @@ func TestPrebindPlugin(t *testing.T) {
|
|||||||
t.Errorf("Expected the pod to be scheduled. error: %v", err)
|
t.Errorf("Expected the pod to be scheduled. error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if preBindPlugin.numPreBindCalled == 0 {
|
p := preBindPlugin.deepCopy()
|
||||||
|
if p.numPreBindCalled == 0 {
|
||||||
t.Errorf("Expected the prebind plugin to be called.")
|
t.Errorf("Expected the prebind plugin to be called.")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1014,7 +1152,7 @@ func TestPrebindPlugin(t *testing.T) {
|
|||||||
if err := wait.Poll(10*time.Millisecond, 15*time.Second, func() (bool, error) {
|
if err := wait.Poll(10*time.Millisecond, 15*time.Second, func() (bool, error) {
|
||||||
// 2 means the unschedulable pod is expected to be retried at least twice.
|
// 2 means the unschedulable pod is expected to be retried at least twice.
|
||||||
// (one initial attempt plus the one moved by the preBind pod)
|
// (one initial attempt plus the one moved by the preBind pod)
|
||||||
return int(filterPlugin.numFilterCalled) >= 2*nodesNum, nil
|
return filterPlugin.deepCopy().numFilterCalled >= 2*nodesNum, nil
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
t.Errorf("Timed out waiting for the unschedulable Pod to be retried at least twice.")
|
t.Errorf("Timed out waiting for the unschedulable Pod to be retried at least twice.")
|
||||||
}
|
}
|
||||||
@ -1523,27 +1661,30 @@ func TestBindPlugin(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("can't get pod: %v", err)
|
t.Errorf("can't get pod: %v", err)
|
||||||
}
|
}
|
||||||
|
p1 := bindPlugin1.deepCopy()
|
||||||
|
p2 := bindPlugin2.deepCopy()
|
||||||
if test.expectBoundByScheduler {
|
if test.expectBoundByScheduler {
|
||||||
if pod.Annotations[bindPluginAnnotation] != "" {
|
if pod.Annotations[bindPluginAnnotation] != "" {
|
||||||
t.Errorf("Expected the pod to be bound by scheduler instead of by bindplugin %s", pod.Annotations[bindPluginAnnotation])
|
t.Errorf("Expected the pod to be bound by scheduler instead of by bindplugin %s", pod.Annotations[bindPluginAnnotation])
|
||||||
}
|
}
|
||||||
if bindPlugin1.numBindCalled != 1 || bindPlugin2.numBindCalled != 1 {
|
if p1.numBindCalled != 1 || p2.numBindCalled != 1 {
|
||||||
t.Errorf("Expected each bind plugin to be called once, was called %d and %d times.", bindPlugin1.numBindCalled, bindPlugin2.numBindCalled)
|
t.Errorf("Expected each bind plugin to be called once, was called %d and %d times.", p1.numBindCalled, p2.numBindCalled)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if pod.Annotations[bindPluginAnnotation] != test.expectBindPluginName {
|
if pod.Annotations[bindPluginAnnotation] != test.expectBindPluginName {
|
||||||
t.Errorf("Expected the pod to be bound by bindplugin %s instead of by bindplugin %s", test.expectBindPluginName, pod.Annotations[bindPluginAnnotation])
|
t.Errorf("Expected the pod to be bound by bindplugin %s instead of by bindplugin %s", test.expectBindPluginName, pod.Annotations[bindPluginAnnotation])
|
||||||
}
|
}
|
||||||
if bindPlugin1.numBindCalled != 1 {
|
if p1.numBindCalled != 1 {
|
||||||
t.Errorf("Expected %s to be called once, was called %d times.", bindPlugin1.Name(), bindPlugin1.numBindCalled)
|
t.Errorf("Expected %s to be called once, was called %d times.", p1.Name(), p1.numBindCalled)
|
||||||
}
|
}
|
||||||
if test.expectBindPluginName == bindPlugin1.Name() && bindPlugin2.numBindCalled > 0 {
|
if test.expectBindPluginName == p1.Name() && p2.numBindCalled > 0 {
|
||||||
// expect bindplugin1 succeeded to bind the pod and bindplugin2 should not be called.
|
// expect bindplugin1 succeeded to bind the pod and bindplugin2 should not be called.
|
||||||
t.Errorf("Expected %s not to be called, was called %d times.", bindPlugin2.Name(), bindPlugin1.numBindCalled)
|
t.Errorf("Expected %s not to be called, was called %d times.", p2.Name(), p2.numBindCalled)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err = wait.Poll(10*time.Millisecond, 30*time.Second, func() (done bool, err error) {
|
if err = wait.Poll(10*time.Millisecond, 30*time.Second, func() (done bool, err error) {
|
||||||
return postBindPlugin.numPostBindCalled == 1, nil
|
p := postBindPlugin.deepCopy()
|
||||||
|
return p.numPostBindCalled == 1, nil
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
t.Errorf("Expected the postbind plugin to be called once, was called %d times.", postBindPlugin.numPostBindCalled)
|
t.Errorf("Expected the postbind plugin to be called once, was called %d times.", postBindPlugin.numPostBindCalled)
|
||||||
}
|
}
|
||||||
@ -1555,8 +1696,9 @@ func TestBindPlugin(t *testing.T) {
|
|||||||
if err = wait.Poll(10*time.Millisecond, 30*time.Second, podSchedulingError(testCtx.ClientSet, pod.Namespace, pod.Name)); err != nil {
|
if err = wait.Poll(10*time.Millisecond, 30*time.Second, podSchedulingError(testCtx.ClientSet, pod.Namespace, pod.Name)); err != nil {
|
||||||
t.Errorf("Expected a scheduling error, but didn't get it. error: %v", err)
|
t.Errorf("Expected a scheduling error, but didn't get it. error: %v", err)
|
||||||
}
|
}
|
||||||
if postBindPlugin.numPostBindCalled > 0 {
|
p := postBindPlugin.deepCopy()
|
||||||
t.Errorf("Didn't expect the postbind plugin to be called %d times.", postBindPlugin.numPostBindCalled)
|
if p.numPostBindCalled > 0 {
|
||||||
|
t.Errorf("Didn't expect the postbind plugin to be called %d times.", p.numPostBindCalled)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for j := range test.expectInvokeEvents {
|
for j := range test.expectInvokeEvents {
|
||||||
@ -1732,7 +1874,8 @@ func TestPermitPlugin(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if perPlugin.numPermitCalled == 0 {
|
p := perPlugin.deepCopy()
|
||||||
|
if p.numPermitCalled == 0 {
|
||||||
t.Errorf("Expected the permit plugin to be called.")
|
t.Errorf("Expected the permit plugin to be called.")
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -1825,7 +1968,9 @@ func TestPermitPluginsCancelled(t *testing.T) {
|
|||||||
perPlugin1.rejectAllPods()
|
perPlugin1.rejectAllPods()
|
||||||
// Wait some time for the permit plugins to be cancelled
|
// Wait some time for the permit plugins to be cancelled
|
||||||
err = wait.Poll(10*time.Millisecond, 30*time.Second, func() (bool, error) {
|
err = wait.Poll(10*time.Millisecond, 30*time.Second, func() (bool, error) {
|
||||||
return perPlugin1.cancelled && perPlugin2.cancelled, nil
|
p1 := perPlugin1.deepCopy()
|
||||||
|
p2 := perPlugin2.deepCopy()
|
||||||
|
return p1.cancelled && p2.cancelled, nil
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Expected all permit plugins to be cancelled")
|
t.Errorf("Expected all permit plugins to be cancelled")
|
||||||
@ -1910,7 +2055,8 @@ func TestCoSchedulingWithPermitPlugin(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if permitPlugin.numPermitCalled == 0 {
|
p := permitPlugin.deepCopy()
|
||||||
|
if p.numPermitCalled == 0 {
|
||||||
t.Errorf("Expected the permit plugin to be called.")
|
t.Errorf("Expected the permit plugin to be called.")
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -2249,9 +2395,8 @@ func TestPreemptWithPermitPlugin(t *testing.T) {
|
|||||||
t.Fatalf("Expected the waiting pod to get preempted.")
|
t.Fatalf("Expected the waiting pod to get preempted.")
|
||||||
}
|
}
|
||||||
|
|
||||||
filterPlugin.RLock()
|
p := filterPlugin.deepCopy()
|
||||||
waitingPodCalled := filterPlugin.numCalledPerPod[fmt.Sprintf("%v/%v", w.Namespace, w.Name)]
|
waitingPodCalled := p.numCalledPerPod[fmt.Sprintf("%v/%v", w.Namespace, w.Name)]
|
||||||
filterPlugin.RUnlock()
|
|
||||||
if waitingPodCalled > tt.maxNumWaitingPodCalled {
|
if waitingPodCalled > tt.maxNumWaitingPodCalled {
|
||||||
t.Fatalf("Expected the waiting pod to be called %v times at most, but got %v", tt.maxNumWaitingPodCalled, waitingPodCalled)
|
t.Fatalf("Expected the waiting pod to be called %v times at most, but got %v", tt.maxNumWaitingPodCalled, waitingPodCalled)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user