Skip to content

Commit

Permalink
add unit tests for version compatibility check
Browse files Browse the repository at this point in the history
  • Loading branch information
a7i committed Mar 22, 2023
1 parent 0872b21 commit 230a3b7
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 10 deletions.
31 changes: 21 additions & 10 deletions pkg/descheduler/descheduler.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@ package descheduler

import (
"context"
"errors"
"fmt"
"math"
"strconv"
"strings"
"time"

"k8s.io/client-go/discovery"
componentbaseconfig "k8s.io/component-base/config"
"k8s.io/klog/v2"

Expand Down Expand Up @@ -88,7 +90,9 @@ func Run(ctx context.Context, rs *options.DeschedulerServer) error {
}

// Add k8s compatibility warnings to logs
versionCompatibilityCheck(rs)
if err := validateVersionCompatibility(rs.Client.Discovery(), version.Get()); err != nil {
klog.Warning(err.Error())
}

evictionPolicyGroupVersion, err := eutils.SupportEviction(rs.Client)
if err != nil || len(evictionPolicyGroupVersion) == 0 {
Expand All @@ -104,7 +108,7 @@ func Run(ctx context.Context, rs *options.DeschedulerServer) error {
}

if rs.LeaderElection.LeaderElect && rs.DryRun {
klog.V(1).InfoS("Warning: DryRun is set to True. You need to disable it to use Leader Election.")
klog.V(1).Info("Warning: DryRun is set to True. You need to disable it to use Leader Election.")
}

if rs.LeaderElection.LeaderElect && !rs.DryRun {
Expand All @@ -117,27 +121,34 @@ func Run(ctx context.Context, rs *options.DeschedulerServer) error {
return runFn()
}

func versionCompatibilityCheck(rs *options.DeschedulerServer) {
serverVersion, serverErr := rs.Client.Discovery().ServerVersion()
func validateVersionCompatibility(discovery discovery.DiscoveryInterface, versionInfo version.Info) error {
serverVersion, serverErr := discovery.ServerVersion()
if serverErr != nil {
klog.V(1).InfoS("Warning: Get Kubernetes server version fail")
return
return errors.New("failed to get Kubernetes server version")
}

deschedulerMinorVersion := strings.Split(version.Get().Minor, ".")[0]
deschedulerMinorVersion := strings.Split(versionInfo.Minor, ".")[0]
deschedulerMinorVersionFloat, err := strconv.ParseFloat(deschedulerMinorVersion, 64)
if err != nil {
klog.Warning("Warning: Convert Descheduler minor version to float fail")
return errors.New("failed to convert Descheduler minor version to float")
}

kubernetesMinorVersionFloat, err := strconv.ParseFloat(serverVersion.Minor, 64)
if err != nil {
klog.Warning("Warning: Convert Kubernetes server minor version to float fail")
return errors.New("failed to convert Kubernetes server minor version to float")
}

if math.Abs(deschedulerMinorVersionFloat-kubernetesMinorVersionFloat) > 3 {
klog.Warningf("Warning: Descheduler minor version %v is not supported on your version of Kubernetes %v.%v. See compatibility docs for more info: https://github.com/kubernetes-sigs/descheduler#compatibility-matrix", deschedulerMinorVersion, serverVersion.Major, serverVersion.Minor)
return fmt.Errorf(
"descheduler minor version %v is not supported on your version of Kubernetes %v.%v. "+
"See compatibility docs for more info: https://github.com/kubernetes-sigs/descheduler#compatibility-matrix",
deschedulerMinorVersion,
serverVersion.Major,
serverVersion.Minor,
)
}

return nil
}

func cachedClient(
Expand Down
60 changes: 60 additions & 0 deletions pkg/descheduler/descheduler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/conversion"
"k8s.io/apimachinery/pkg/runtime"
apiversion "k8s.io/apimachinery/pkg/version"
fakediscovery "k8s.io/client-go/discovery/fake"
fakeclientset "k8s.io/client-go/kubernetes/fake"
core "k8s.io/client-go/testing"
"sigs.k8s.io/descheduler/cmd/descheduler/app/options"
Expand All @@ -19,6 +21,7 @@ import (
"sigs.k8s.io/descheduler/pkg/framework/pluginregistry"
"sigs.k8s.io/descheduler/pkg/framework/plugins/removeduplicates"
"sigs.k8s.io/descheduler/pkg/framework/plugins/removepodsviolatingnodetaints"
deschedulerversion "sigs.k8s.io/descheduler/pkg/version"
"sigs.k8s.io/descheduler/test"
)

Expand Down Expand Up @@ -240,6 +243,63 @@ func TestRootCancelWithNoInterval(t *testing.T) {
}
}

func TestValidateVersionCompatibility(t *testing.T) {
type testCase struct {
name string
deschedulerMinor string
serverMinor string
expectError bool
}
testCases := []testCase{
{
name: "no error when descheduler minor equals to server minor",
deschedulerMinor: "26",
serverMinor: "26",
expectError: false,
},
{
name: "no error when descheduler minor is 3 behind server minor",
deschedulerMinor: "23",
serverMinor: "26",
expectError: false,
},
{
name: "no error when descheduler minor is 3 ahead of server minor",
deschedulerMinor: "26",
serverMinor: "23",
expectError: false,
},
{
name: "error when descheduler minor is 4 behind server minor",
deschedulerMinor: "22",
serverMinor: "26",
expectError: true,
},
{
name: "error when descheduler minor is 4 ahead of server minor",
deschedulerMinor: "26",
serverMinor: "22",
expectError: true,
},
}
client := fakeclientset.NewSimpleClientset()
fakeDiscovery, _ := client.Discovery().(*fakediscovery.FakeDiscovery)
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()

fakeDiscovery.FakedServerVersion = &apiversion.Info{Major: "1", Minor: tc.serverMinor}
deschedulerVersion := deschedulerversion.Info{Major: "0", Minor: tc.deschedulerMinor}
err := validateVersionCompatibility(fakeDiscovery, deschedulerVersion)

hasError := err != nil
if tc.expectError != hasError {
t.Error("unexpected version compatibility behavior")
}
})
}
}

func podEvictionReactionFuc(evictedPods *[]string) func(action core.Action) (bool, runtime.Object, error) {
return func(action core.Action) (bool, runtime.Object, error) {
if action.GetSubresource() == "eviction" {
Expand Down

0 comments on commit 230a3b7

Please sign in to comment.