diff --git a/cmd/kube-scheduler/app/server_test.go b/cmd/kube-scheduler/app/server_test.go index f5e8c061ff6..c6b52185a23 100644 --- a/cmd/kube-scheduler/app/server_test.go +++ b/cmd/kube-scheduler/app/server_test.go @@ -26,13 +26,16 @@ import ( "os" "path/filepath" "testing" + "time" "github.com/google/go-cmp/cmp" "github.com/spf13/pflag" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apiserver/pkg/util/feature" componentbaseconfig "k8s.io/component-base/config" "k8s.io/component-base/featuregate" featuregatetesting "k8s.io/component-base/featuregate/testing" + "k8s.io/kube-scheduler/config/v1beta3" "k8s.io/kubernetes/cmd/kube-scheduler/app/options" "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/scheduler/apis/config" @@ -145,6 +148,30 @@ profiles: t.Fatal(err) } + // empty leader-election config + emptyLeaderElectionConfig := filepath.Join(tmpDir, "empty-leader-election-config.yaml") + if err := ioutil.WriteFile(emptyLeaderElectionConfig, []byte(fmt.Sprintf(` +apiVersion: kubescheduler.config.k8s.io/v1beta3 +kind: KubeSchedulerConfiguration +clientConnection: + kubeconfig: "%s" +`, configKubeconfig)), os.FileMode(0600)); err != nil { + t.Fatal(err) + } + + // leader-election config + leaderElectionConfig := filepath.Join(tmpDir, "leader-election-config.yaml") + if err := ioutil.WriteFile(leaderElectionConfig, []byte(fmt.Sprintf(` +apiVersion: kubescheduler.config.k8s.io/v1beta3 +kind: KubeSchedulerConfiguration +clientConnection: + kubeconfig: "%s" +leaderElection: + leaseDuration: 1h +`, configKubeconfig)), os.FileMode(0600)); err != nil { + t.Fatal(err) + } + testcases := []struct { name string flags []string @@ -234,6 +261,75 @@ profiles: }, }, }, + { + name: "leader election CLI args, along with --config arg", + flags: []string{ + "--leader-elect=false", + "--leader-elect-lease-duration=2h", // CLI args are favored over the fields in ComponentConfig + "--lock-object-namespace=default", // deprecated CLI arg will be ignored if --config is specified + "--config", emptyLeaderElectionConfig, + }, + wantLeaderElection: &componentbaseconfig.LeaderElectionConfiguration{ + LeaderElect: false, // from CLI args + LeaseDuration: metav1.Duration{Duration: 2 * time.Hour}, // from CLI args + RenewDeadline: metav1.Duration{Duration: 10 * time.Second}, + RetryPeriod: metav1.Duration{Duration: 2 * time.Second}, + ResourceLock: "leases", + ResourceName: v1beta3.SchedulerDefaultLockObjectName, + ResourceNamespace: v1beta3.SchedulerDefaultLockObjectNamespace, + }, + }, + { + name: "leader election CLI args, without --config arg", + flags: []string{ + "--leader-elect=false", + "--leader-elect-lease-duration=2h", + "--lock-object-namespace=default", // deprecated CLI arg is honored if --config is not specified + "--kubeconfig", configKubeconfig, + }, + wantLeaderElection: &componentbaseconfig.LeaderElectionConfiguration{ + LeaderElect: false, // from CLI args + LeaseDuration: metav1.Duration{Duration: 2 * time.Hour}, // from CLI args + RenewDeadline: metav1.Duration{Duration: 10 * time.Second}, + RetryPeriod: metav1.Duration{Duration: 2 * time.Second}, + ResourceLock: "leases", + ResourceName: v1beta3.SchedulerDefaultLockObjectName, + ResourceNamespace: "default", // from deprecated CLI args + }, + }, + { + name: "leader election settings specified by ComponentConfig only", + flags: []string{ + "--config", leaderElectionConfig, + }, + wantLeaderElection: &componentbaseconfig.LeaderElectionConfiguration{ + LeaderElect: true, + LeaseDuration: metav1.Duration{Duration: 1 * time.Hour}, // from CC + RenewDeadline: metav1.Duration{Duration: 10 * time.Second}, + RetryPeriod: metav1.Duration{Duration: 2 * time.Second}, + ResourceLock: "leases", + ResourceName: v1beta3.SchedulerDefaultLockObjectName, + ResourceNamespace: v1beta3.SchedulerDefaultLockObjectNamespace, + }, + }, + { + name: "leader election settings specified by CLI args and ComponentConfig", + flags: []string{ + "--leader-elect=true", + "--leader-elect-renew-deadline=5s", + "--leader-elect-retry-period=1s", + "--config", leaderElectionConfig, + }, + wantLeaderElection: &componentbaseconfig.LeaderElectionConfiguration{ + LeaderElect: true, + LeaseDuration: metav1.Duration{Duration: 1 * time.Hour}, // from CC + RenewDeadline: metav1.Duration{Duration: 5 * time.Second}, // from CLI args + RetryPeriod: metav1.Duration{Duration: 1 * time.Second}, // from CLI args + ResourceLock: "leases", + ResourceName: v1beta3.SchedulerDefaultLockObjectName, + ResourceNamespace: v1beta3.SchedulerDefaultLockObjectNamespace, + }, + }, } makeListener := func(t *testing.T) net.Listener { @@ -277,13 +373,22 @@ profiles: t.Fatal(err) } - gotPlugins := make(map[string]*config.Plugins) - for n, p := range sched.Profiles { - gotPlugins[n] = p.ListPlugins() + if tc.wantPlugins != nil { + gotPlugins := make(map[string]*config.Plugins) + for n, p := range sched.Profiles { + gotPlugins[n] = p.ListPlugins() + } + + if diff := cmp.Diff(tc.wantPlugins, gotPlugins); diff != "" { + t.Errorf("Unexpected plugins diff (-want, +got): %s", diff) + } } - if diff := cmp.Diff(tc.wantPlugins, gotPlugins); diff != "" { - t.Errorf("unexpected plugins diff (-want, +got): %s", diff) + if tc.wantLeaderElection != nil { + gotLeaderElection := opts.ComponentConfig.LeaderElection + if diff := cmp.Diff(*tc.wantLeaderElection, gotLeaderElection); diff != "" { + t.Errorf("Unexpected leaderElection diff (-want, +got): %s", diff) + } } }) }