...

Source file src/k8s.io/kubernetes/test/integration/scheduler/util.go

Documentation: k8s.io/kubernetes/test/integration/scheduler

     1  /*
     2  Copyright 2017 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 scheduler
    18  
    19  import (
    20  	"context"
    21  	"testing"
    22  	"time"
    23  
    24  	v1 "k8s.io/api/core/v1"
    25  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    26  	"k8s.io/apimachinery/pkg/runtime"
    27  	"k8s.io/apimachinery/pkg/util/wait"
    28  	configv1 "k8s.io/kube-scheduler/config/v1"
    29  	"k8s.io/kubernetes/pkg/scheduler"
    30  	schedulerconfig "k8s.io/kubernetes/pkg/scheduler/apis/config"
    31  	configtesting "k8s.io/kubernetes/pkg/scheduler/apis/config/testing"
    32  	"k8s.io/kubernetes/pkg/scheduler/framework"
    33  	"k8s.io/kubernetes/pkg/scheduler/framework/plugins/defaultbinder"
    34  	frameworkruntime "k8s.io/kubernetes/pkg/scheduler/framework/runtime"
    35  	st "k8s.io/kubernetes/pkg/scheduler/testing"
    36  	testutils "k8s.io/kubernetes/test/integration/util"
    37  	"k8s.io/utils/pointer"
    38  )
    39  
    40  // The returned shutdown func will delete created resources and scheduler, resources should be those
    41  // that will affect the scheduling result, like nodes, pods, etc.. Namespaces should not be
    42  // deleted here because it's created together with the apiserver, they should be deleted
    43  // simultaneously or we'll have no namespace.
    44  // This should only be called when you want to kill the scheduler alone, away from apiserver.
    45  // For example, in scheduler integration tests, recreating apiserver is performance consuming,
    46  // then shutdown the scheduler and recreate it between each test case is a better approach.
    47  func InitTestSchedulerForFrameworkTest(t *testing.T, testCtx *testutils.TestContext, nodeCount int, opts ...scheduler.Option) (*testutils.TestContext, testutils.ShutdownFunc) {
    48  	testCtx = testutils.InitTestSchedulerWithOptions(t, testCtx, 0, opts...)
    49  	testutils.SyncSchedulerInformerFactory(testCtx)
    50  	go testCtx.Scheduler.Run(testCtx.SchedulerCtx)
    51  
    52  	if nodeCount > 0 {
    53  		if _, err := testutils.CreateAndWaitForNodesInCache(testCtx, "test-node", st.MakeNode(), nodeCount); err != nil {
    54  			// Make sure to cleanup the resources when initializing error.
    55  			testutils.CleanupTest(t, testCtx)
    56  			t.Fatal(err)
    57  		}
    58  	}
    59  
    60  	teardown := func() {
    61  		err := testCtx.ClientSet.CoreV1().Nodes().DeleteCollection(testCtx.SchedulerCtx, *metav1.NewDeleteOptions(0), metav1.ListOptions{})
    62  		if err != nil {
    63  			t.Errorf("error while deleting all nodes: %v", err)
    64  		}
    65  		err = testCtx.ClientSet.CoreV1().Pods(testCtx.NS.Name).DeleteCollection(testCtx.SchedulerCtx, *metav1.NewDeleteOptions(0), metav1.ListOptions{})
    66  		if err != nil {
    67  			t.Errorf("error while deleting pod: %v", err)
    68  		}
    69  		// Wait for all pods to be deleted, or will failed to create same name pods
    70  		// required in other test cases.
    71  		err = wait.PollUntilContextTimeout(testCtx.SchedulerCtx, time.Millisecond, wait.ForeverTestTimeout, true,
    72  			testutils.PodsCleanedUp(testCtx.SchedulerCtx, testCtx.ClientSet, testCtx.NS.Name))
    73  		if err != nil {
    74  			t.Errorf("error while waiting for all pods to be deleted: %v", err)
    75  		}
    76  		// Kill the scheduler.
    77  		testCtx.SchedulerCloseFn()
    78  	}
    79  
    80  	return testCtx, teardown
    81  }
    82  
    83  // NewPlugin returns a plugin factory with specified Plugin.
    84  func NewPlugin(plugin framework.Plugin) frameworkruntime.PluginFactory {
    85  	return func(_ context.Context, _ runtime.Object, fh framework.Handle) (framework.Plugin, error) {
    86  		return plugin, nil
    87  	}
    88  }
    89  
    90  // InitRegistryAndConfig returns registry and plugins config based on give plugins.
    91  func InitRegistryAndConfig(t *testing.T, factory func(plugin framework.Plugin) frameworkruntime.PluginFactory, plugins ...framework.Plugin) (frameworkruntime.Registry, schedulerconfig.KubeSchedulerProfile) {
    92  	if len(plugins) == 0 {
    93  		return frameworkruntime.Registry{}, schedulerconfig.KubeSchedulerProfile{}
    94  	}
    95  
    96  	if factory == nil {
    97  		factory = NewPlugin
    98  	}
    99  
   100  	registry := frameworkruntime.Registry{}
   101  	pls := &configv1.Plugins{}
   102  
   103  	for _, p := range plugins {
   104  		registry.Register(p.Name(), factory(p))
   105  		plugin := configv1.Plugin{Name: p.Name()}
   106  
   107  		switch p.(type) {
   108  		case framework.PreEnqueuePlugin:
   109  			pls.PreEnqueue.Enabled = append(pls.PreEnqueue.Enabled, plugin)
   110  		case framework.PreFilterPlugin:
   111  			pls.PreFilter.Enabled = append(pls.PreFilter.Enabled, plugin)
   112  		case framework.FilterPlugin:
   113  			pls.Filter.Enabled = append(pls.Filter.Enabled, plugin)
   114  		case framework.PreScorePlugin:
   115  			pls.PreScore.Enabled = append(pls.PreScore.Enabled, plugin)
   116  		case framework.ScorePlugin:
   117  			pls.Score.Enabled = append(pls.Score.Enabled, plugin)
   118  		case framework.ReservePlugin:
   119  			pls.Reserve.Enabled = append(pls.Reserve.Enabled, plugin)
   120  		case framework.PreBindPlugin:
   121  			pls.PreBind.Enabled = append(pls.PreBind.Enabled, plugin)
   122  		case framework.BindPlugin:
   123  			pls.Bind.Enabled = append(pls.Bind.Enabled, plugin)
   124  			// It's intentional to disable the DefaultBind plugin. Otherwise, DefaultBinder's failure would fail
   125  			// a pod's scheduling, as well as the test BindPlugin's execution.
   126  			pls.Bind.Disabled = []configv1.Plugin{{Name: defaultbinder.Name}}
   127  		case framework.PostBindPlugin:
   128  			pls.PostBind.Enabled = append(pls.PostBind.Enabled, plugin)
   129  		case framework.PermitPlugin:
   130  			pls.Permit.Enabled = append(pls.Permit.Enabled, plugin)
   131  		}
   132  	}
   133  
   134  	versionedCfg := configv1.KubeSchedulerConfiguration{
   135  		Profiles: []configv1.KubeSchedulerProfile{{
   136  			SchedulerName: pointer.String(v1.DefaultSchedulerName),
   137  			Plugins:       pls,
   138  		}},
   139  	}
   140  	cfg := configtesting.V1ToInternalWithDefaults(t, versionedCfg)
   141  	return registry, cfg.Profiles[0]
   142  }
   143  

View as plain text