Added tests for scheduler/framework/plugins
Signed-off-by: Anuj Agrawal <anujagrawal380@gmail.com> Added tests for scheduler/framework/plugins Signed-off-by: Anuj Agrawal <anujagrawal380@gmail.com>
This commit is contained in:
parent
6b18b6e120
commit
e818659bb2
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
Copyright 2024 The Karmada Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package apienablement
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
clusterv1alpha1 "github.com/karmada-io/karmada/pkg/apis/cluster/v1alpha1"
|
||||
workv1alpha2 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha2"
|
||||
"github.com/karmada-io/karmada/pkg/scheduler/framework"
|
||||
)
|
||||
|
||||
func TestAPIEnablement_Filter(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
bindingSpec *workv1alpha2.ResourceBindingSpec
|
||||
cluster *clusterv1alpha1.Cluster
|
||||
expectedCode framework.Code
|
||||
expectError bool
|
||||
}{
|
||||
{
|
||||
name: "API is enabled in cluster",
|
||||
bindingSpec: &workv1alpha2.ResourceBindingSpec{
|
||||
Resource: workv1alpha2.ObjectReference{
|
||||
APIVersion: "apps/v1",
|
||||
Kind: "Deployment",
|
||||
},
|
||||
},
|
||||
cluster: &clusterv1alpha1.Cluster{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "cluster1",
|
||||
},
|
||||
Status: clusterv1alpha1.ClusterStatus{
|
||||
APIEnablements: []clusterv1alpha1.APIEnablement{
|
||||
{
|
||||
GroupVersion: "apps/v1",
|
||||
Resources: []clusterv1alpha1.APIResource{
|
||||
{
|
||||
Kind: "Deployment",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedCode: framework.Success,
|
||||
expectError: false,
|
||||
},
|
||||
{
|
||||
name: "API is not enabled in cluster",
|
||||
bindingSpec: &workv1alpha2.ResourceBindingSpec{
|
||||
Resource: workv1alpha2.ObjectReference{
|
||||
APIVersion: "custom.io/v1",
|
||||
Kind: "CustomResource",
|
||||
},
|
||||
},
|
||||
cluster: &clusterv1alpha1.Cluster{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "cluster1",
|
||||
},
|
||||
Status: clusterv1alpha1.ClusterStatus{
|
||||
APIEnablements: []clusterv1alpha1.APIEnablement{
|
||||
{
|
||||
GroupVersion: "apps/v1",
|
||||
Resources: []clusterv1alpha1.APIResource{
|
||||
{
|
||||
Kind: "Deployment",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedCode: framework.Unschedulable,
|
||||
expectError: true,
|
||||
},
|
||||
{
|
||||
name: "cluster in target list with incomplete API enablements",
|
||||
bindingSpec: &workv1alpha2.ResourceBindingSpec{
|
||||
Resource: workv1alpha2.ObjectReference{
|
||||
APIVersion: "custom.io/v1",
|
||||
Kind: "CustomResource",
|
||||
},
|
||||
Clusters: []workv1alpha2.TargetCluster{
|
||||
{
|
||||
Name: "cluster1",
|
||||
},
|
||||
},
|
||||
},
|
||||
cluster: &clusterv1alpha1.Cluster{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "cluster1",
|
||||
},
|
||||
Status: clusterv1alpha1.ClusterStatus{
|
||||
Conditions: []metav1.Condition{
|
||||
{
|
||||
Type: clusterv1alpha1.ClusterConditionCompleteAPIEnablements,
|
||||
Status: metav1.ConditionFalse,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedCode: framework.Success,
|
||||
expectError: false,
|
||||
},
|
||||
}
|
||||
|
||||
p := &APIEnablement{}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result := p.Filter(context.Background(), tt.bindingSpec, nil, tt.cluster)
|
||||
assert.Equal(t, tt.expectedCode, result.Code())
|
||||
assert.Equal(t, tt.expectError, result.AsError() != nil)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestNew(t *testing.T) {
|
||||
plugin, err := New()
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, plugin)
|
||||
_, ok := plugin.(*APIEnablement)
|
||||
assert.True(t, ok)
|
||||
}
|
||||
|
||||
func TestAPIEnablement_Name(t *testing.T) {
|
||||
p := &APIEnablement{}
|
||||
assert.Equal(t, Name, p.Name())
|
||||
}
|
|
@ -0,0 +1,160 @@
|
|||
/*
|
||||
Copyright 2024 The Karmada Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package clusteraffinity
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
clusterv1alpha1 "github.com/karmada-io/karmada/pkg/apis/cluster/v1alpha1"
|
||||
policyv1alpha1 "github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1"
|
||||
workv1alpha2 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha2"
|
||||
"github.com/karmada-io/karmada/pkg/scheduler/framework"
|
||||
)
|
||||
|
||||
func TestClusterAffinity_Filter(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
bindingSpec *workv1alpha2.ResourceBindingSpec
|
||||
bindingStatus *workv1alpha2.ResourceBindingStatus
|
||||
cluster *clusterv1alpha1.Cluster
|
||||
expectedCode framework.Code
|
||||
expectError bool
|
||||
}{
|
||||
{
|
||||
name: "matching affinity",
|
||||
bindingSpec: &workv1alpha2.ResourceBindingSpec{
|
||||
Placement: &policyv1alpha1.Placement{
|
||||
ClusterAffinity: &policyv1alpha1.ClusterAffinity{
|
||||
ClusterNames: []string{"cluster1"},
|
||||
},
|
||||
},
|
||||
},
|
||||
cluster: &clusterv1alpha1.Cluster{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "cluster1",
|
||||
},
|
||||
},
|
||||
expectedCode: framework.Success,
|
||||
expectError: false,
|
||||
},
|
||||
{
|
||||
name: "non-matching affinity",
|
||||
bindingSpec: &workv1alpha2.ResourceBindingSpec{
|
||||
Placement: &policyv1alpha1.Placement{
|
||||
ClusterAffinity: &policyv1alpha1.ClusterAffinity{
|
||||
ClusterNames: []string{"cluster2"},
|
||||
},
|
||||
},
|
||||
},
|
||||
cluster: &clusterv1alpha1.Cluster{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "cluster1",
|
||||
},
|
||||
},
|
||||
expectedCode: framework.Unschedulable,
|
||||
expectError: true,
|
||||
},
|
||||
{
|
||||
name: "matching affinity from ClusterAffinities",
|
||||
bindingSpec: &workv1alpha2.ResourceBindingSpec{
|
||||
Placement: &policyv1alpha1.Placement{
|
||||
ClusterAffinities: []policyv1alpha1.ClusterAffinityTerm{
|
||||
{
|
||||
AffinityName: "affinity1",
|
||||
ClusterAffinity: policyv1alpha1.ClusterAffinity{
|
||||
ClusterNames: []string{"cluster1"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
bindingStatus: &workv1alpha2.ResourceBindingStatus{
|
||||
SchedulerObservedAffinityName: "affinity1",
|
||||
},
|
||||
cluster: &clusterv1alpha1.Cluster{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "cluster1",
|
||||
},
|
||||
},
|
||||
expectedCode: framework.Success,
|
||||
expectError: false,
|
||||
},
|
||||
{
|
||||
name: "no affinity specified",
|
||||
bindingSpec: &workv1alpha2.ResourceBindingSpec{
|
||||
Placement: &policyv1alpha1.Placement{},
|
||||
},
|
||||
cluster: &clusterv1alpha1.Cluster{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "cluster1",
|
||||
},
|
||||
},
|
||||
expectedCode: framework.Success,
|
||||
expectError: false,
|
||||
},
|
||||
}
|
||||
|
||||
p := &ClusterAffinity{}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result := p.Filter(context.Background(), tt.bindingSpec, tt.bindingStatus, tt.cluster)
|
||||
assert.Equal(t, tt.expectedCode, result.Code())
|
||||
assert.Equal(t, tt.expectError, result.AsError() != nil)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestClusterAffinity_Score(t *testing.T) {
|
||||
p := &ClusterAffinity{}
|
||||
spec := &workv1alpha2.ResourceBindingSpec{}
|
||||
cluster := &clusterv1alpha1.Cluster{}
|
||||
|
||||
score, result := p.Score(context.Background(), spec, cluster)
|
||||
|
||||
assert.Equal(t, framework.MinClusterScore, score)
|
||||
assert.Equal(t, framework.Success, result.Code())
|
||||
}
|
||||
|
||||
func TestClusterAffinity_ScoreExtensions(t *testing.T) {
|
||||
p := &ClusterAffinity{}
|
||||
assert.Equal(t, p, p.ScoreExtensions())
|
||||
}
|
||||
|
||||
func TestClusterAffinity_NormalizeScore(t *testing.T) {
|
||||
p := &ClusterAffinity{}
|
||||
result := p.NormalizeScore(context.Background(), nil)
|
||||
assert.Equal(t, framework.Success, result.Code())
|
||||
}
|
||||
|
||||
func TestNew(t *testing.T) {
|
||||
plugin, err := New()
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, plugin)
|
||||
_, ok := plugin.(*ClusterAffinity)
|
||||
assert.True(t, ok)
|
||||
}
|
||||
|
||||
func TestClusterAffinity_Name(t *testing.T) {
|
||||
p := &ClusterAffinity{}
|
||||
assert.Equal(t, Name, p.Name())
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
Copyright 2024 The Karmada Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package clustereviction
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
clusterv1alpha1 "github.com/karmada-io/karmada/pkg/apis/cluster/v1alpha1"
|
||||
workv1alpha2 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha2"
|
||||
"github.com/karmada-io/karmada/pkg/scheduler/framework"
|
||||
)
|
||||
|
||||
func TestClusterEviction_Filter(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
bindingSpec *workv1alpha2.ResourceBindingSpec
|
||||
cluster *clusterv1alpha1.Cluster
|
||||
expectedCode framework.Code
|
||||
expectError bool
|
||||
}{
|
||||
{
|
||||
name: "cluster is in graceful eviction tasks",
|
||||
bindingSpec: &workv1alpha2.ResourceBindingSpec{
|
||||
GracefulEvictionTasks: []workv1alpha2.GracefulEvictionTask{
|
||||
{
|
||||
FromCluster: "cluster1",
|
||||
},
|
||||
},
|
||||
},
|
||||
cluster: &clusterv1alpha1.Cluster{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "cluster1",
|
||||
},
|
||||
},
|
||||
expectedCode: framework.Unschedulable,
|
||||
expectError: true,
|
||||
},
|
||||
{
|
||||
name: "cluster is not in graceful eviction tasks",
|
||||
bindingSpec: &workv1alpha2.ResourceBindingSpec{
|
||||
GracefulEvictionTasks: []workv1alpha2.GracefulEvictionTask{
|
||||
{
|
||||
FromCluster: "cluster2",
|
||||
},
|
||||
},
|
||||
},
|
||||
cluster: &clusterv1alpha1.Cluster{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "cluster1",
|
||||
},
|
||||
},
|
||||
expectedCode: framework.Success,
|
||||
expectError: false,
|
||||
},
|
||||
{
|
||||
name: "no graceful eviction tasks",
|
||||
bindingSpec: &workv1alpha2.ResourceBindingSpec{},
|
||||
cluster: &clusterv1alpha1.Cluster{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "cluster1",
|
||||
},
|
||||
},
|
||||
expectedCode: framework.Success,
|
||||
expectError: false,
|
||||
},
|
||||
}
|
||||
|
||||
p := &ClusterEviction{}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result := p.Filter(context.Background(), tt.bindingSpec, nil, tt.cluster)
|
||||
assert.Equal(t, tt.expectedCode, result.Code())
|
||||
assert.Equal(t, tt.expectError, result.AsError() != nil)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestNew(t *testing.T) {
|
||||
plugin, err := New()
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, plugin)
|
||||
_, ok := plugin.(*ClusterEviction)
|
||||
assert.True(t, ok)
|
||||
}
|
||||
|
||||
func TestClusterEviction_Name(t *testing.T) {
|
||||
p := &ClusterEviction{}
|
||||
assert.Equal(t, Name, p.Name())
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
Copyright 2024 The Karmada Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package clusterlocality
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
clusterv1alpha1 "github.com/karmada-io/karmada/pkg/apis/cluster/v1alpha1"
|
||||
workv1alpha2 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha2"
|
||||
"github.com/karmada-io/karmada/pkg/scheduler/framework"
|
||||
)
|
||||
|
||||
func TestClusterLocality_Score(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
bindingSpec *workv1alpha2.ResourceBindingSpec
|
||||
cluster *clusterv1alpha1.Cluster
|
||||
expectedScore int64
|
||||
}{
|
||||
{
|
||||
name: "no clusters in spec",
|
||||
bindingSpec: &workv1alpha2.ResourceBindingSpec{
|
||||
Clusters: []workv1alpha2.TargetCluster{},
|
||||
},
|
||||
cluster: &clusterv1alpha1.Cluster{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "cluster1",
|
||||
},
|
||||
},
|
||||
expectedScore: framework.MinClusterScore,
|
||||
},
|
||||
{
|
||||
name: "cluster in spec",
|
||||
bindingSpec: &workv1alpha2.ResourceBindingSpec{
|
||||
Clusters: []workv1alpha2.TargetCluster{
|
||||
{Name: "cluster1"},
|
||||
{Name: "cluster2"},
|
||||
},
|
||||
},
|
||||
cluster: &clusterv1alpha1.Cluster{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "cluster1",
|
||||
},
|
||||
},
|
||||
expectedScore: framework.MaxClusterScore,
|
||||
},
|
||||
{
|
||||
name: "cluster not in spec",
|
||||
bindingSpec: &workv1alpha2.ResourceBindingSpec{
|
||||
Clusters: []workv1alpha2.TargetCluster{
|
||||
{Name: "cluster2"},
|
||||
{Name: "cluster3"},
|
||||
},
|
||||
},
|
||||
cluster: &clusterv1alpha1.Cluster{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "cluster1",
|
||||
},
|
||||
},
|
||||
expectedScore: framework.MinClusterScore,
|
||||
},
|
||||
}
|
||||
|
||||
p := &ClusterLocality{}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
score, result := p.Score(context.Background(), tt.bindingSpec, tt.cluster)
|
||||
assert.Equal(t, tt.expectedScore, score)
|
||||
assert.Equal(t, framework.Success, result.Code())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestNew(t *testing.T) {
|
||||
plugin, err := New()
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, plugin)
|
||||
_, ok := plugin.(*ClusterLocality)
|
||||
assert.True(t, ok)
|
||||
}
|
||||
|
||||
func TestClusterLocality_Name(t *testing.T) {
|
||||
p := &ClusterLocality{}
|
||||
assert.Equal(t, Name, p.Name())
|
||||
}
|
||||
|
||||
func TestClusterLocality_ScoreExtensions(t *testing.T) {
|
||||
p := &ClusterLocality{}
|
||||
assert.Nil(t, p.ScoreExtensions())
|
||||
}
|
|
@ -0,0 +1,160 @@
|
|||
/*
|
||||
Copyright 2024 The Karmada Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package spreadconstraint
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
clusterv1alpha1 "github.com/karmada-io/karmada/pkg/apis/cluster/v1alpha1"
|
||||
policyv1alpha1 "github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1"
|
||||
workv1alpha2 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha2"
|
||||
"github.com/karmada-io/karmada/pkg/scheduler/framework"
|
||||
)
|
||||
|
||||
func TestSpreadConstraint_Filter(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
bindingSpec *workv1alpha2.ResourceBindingSpec
|
||||
cluster *clusterv1alpha1.Cluster
|
||||
expectedCode framework.Code
|
||||
expectedReason string
|
||||
}{
|
||||
{
|
||||
name: "no spread constraints",
|
||||
bindingSpec: &workv1alpha2.ResourceBindingSpec{
|
||||
Placement: &policyv1alpha1.Placement{},
|
||||
},
|
||||
cluster: &clusterv1alpha1.Cluster{},
|
||||
expectedCode: framework.Success,
|
||||
},
|
||||
{
|
||||
name: "spread by provider - provider present",
|
||||
bindingSpec: &workv1alpha2.ResourceBindingSpec{
|
||||
Placement: &policyv1alpha1.Placement{
|
||||
SpreadConstraints: []policyv1alpha1.SpreadConstraint{
|
||||
{SpreadByField: policyv1alpha1.SpreadByFieldProvider},
|
||||
},
|
||||
},
|
||||
},
|
||||
cluster: &clusterv1alpha1.Cluster{
|
||||
Spec: clusterv1alpha1.ClusterSpec{
|
||||
Provider: "aws",
|
||||
},
|
||||
},
|
||||
expectedCode: framework.Success,
|
||||
},
|
||||
{
|
||||
name: "spread by provider - provider missing",
|
||||
bindingSpec: &workv1alpha2.ResourceBindingSpec{
|
||||
Placement: &policyv1alpha1.Placement{
|
||||
SpreadConstraints: []policyv1alpha1.SpreadConstraint{
|
||||
{SpreadByField: policyv1alpha1.SpreadByFieldProvider},
|
||||
},
|
||||
},
|
||||
},
|
||||
cluster: &clusterv1alpha1.Cluster{},
|
||||
expectedCode: framework.Unschedulable,
|
||||
expectedReason: "cluster(s) did not have provider property",
|
||||
},
|
||||
{
|
||||
name: "spread by region - region present",
|
||||
bindingSpec: &workv1alpha2.ResourceBindingSpec{
|
||||
Placement: &policyv1alpha1.Placement{
|
||||
SpreadConstraints: []policyv1alpha1.SpreadConstraint{
|
||||
{SpreadByField: policyv1alpha1.SpreadByFieldRegion},
|
||||
},
|
||||
},
|
||||
},
|
||||
cluster: &clusterv1alpha1.Cluster{
|
||||
Spec: clusterv1alpha1.ClusterSpec{
|
||||
Region: "us-west-2",
|
||||
},
|
||||
},
|
||||
expectedCode: framework.Success,
|
||||
},
|
||||
{
|
||||
name: "spread by region - region missing",
|
||||
bindingSpec: &workv1alpha2.ResourceBindingSpec{
|
||||
Placement: &policyv1alpha1.Placement{
|
||||
SpreadConstraints: []policyv1alpha1.SpreadConstraint{
|
||||
{SpreadByField: policyv1alpha1.SpreadByFieldRegion},
|
||||
},
|
||||
},
|
||||
},
|
||||
cluster: &clusterv1alpha1.Cluster{},
|
||||
expectedCode: framework.Unschedulable,
|
||||
expectedReason: "cluster(s) did not have region property",
|
||||
},
|
||||
{
|
||||
name: "spread by zone - zones present",
|
||||
bindingSpec: &workv1alpha2.ResourceBindingSpec{
|
||||
Placement: &policyv1alpha1.Placement{
|
||||
SpreadConstraints: []policyv1alpha1.SpreadConstraint{
|
||||
{SpreadByField: policyv1alpha1.SpreadByFieldZone},
|
||||
},
|
||||
},
|
||||
},
|
||||
cluster: &clusterv1alpha1.Cluster{
|
||||
Spec: clusterv1alpha1.ClusterSpec{
|
||||
Zones: []string{"us-west-2a"},
|
||||
},
|
||||
},
|
||||
expectedCode: framework.Success,
|
||||
},
|
||||
{
|
||||
name: "spread by zone - zones missing",
|
||||
bindingSpec: &workv1alpha2.ResourceBindingSpec{
|
||||
Placement: &policyv1alpha1.Placement{
|
||||
SpreadConstraints: []policyv1alpha1.SpreadConstraint{
|
||||
{SpreadByField: policyv1alpha1.SpreadByFieldZone},
|
||||
},
|
||||
},
|
||||
},
|
||||
cluster: &clusterv1alpha1.Cluster{},
|
||||
expectedCode: framework.Unschedulable,
|
||||
expectedReason: "cluster(s) did not have zones property",
|
||||
},
|
||||
}
|
||||
|
||||
p := &SpreadConstraint{}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result := p.Filter(context.Background(), tt.bindingSpec, nil, tt.cluster)
|
||||
assert.Equal(t, tt.expectedCode, result.Code())
|
||||
if tt.expectedReason != "" {
|
||||
assert.Contains(t, result.AsError().Error(), tt.expectedReason)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestNew(t *testing.T) {
|
||||
plugin, err := New()
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, plugin)
|
||||
_, ok := plugin.(*SpreadConstraint)
|
||||
assert.True(t, ok)
|
||||
}
|
||||
|
||||
func TestSpreadConstraint_Name(t *testing.T) {
|
||||
p := &SpreadConstraint{}
|
||||
assert.Equal(t, Name, p.Name())
|
||||
}
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
Copyright 2024 The Karmada Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package tainttoleration
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
clusterv1alpha1 "github.com/karmada-io/karmada/pkg/apis/cluster/v1alpha1"
|
||||
policyv1alpha1 "github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1"
|
||||
workv1alpha2 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha2"
|
||||
"github.com/karmada-io/karmada/pkg/scheduler/framework"
|
||||
)
|
||||
|
||||
func TestTaintToleration_Filter(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
bindingSpec *workv1alpha2.ResourceBindingSpec
|
||||
cluster *clusterv1alpha1.Cluster
|
||||
expectedCode framework.Code
|
||||
expectedReason string
|
||||
}{
|
||||
{
|
||||
name: "cluster already in target clusters",
|
||||
bindingSpec: &workv1alpha2.ResourceBindingSpec{
|
||||
Clusters: []workv1alpha2.TargetCluster{
|
||||
{Name: "cluster1"},
|
||||
},
|
||||
},
|
||||
cluster: &clusterv1alpha1.Cluster{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "cluster1",
|
||||
},
|
||||
},
|
||||
expectedCode: framework.Success,
|
||||
},
|
||||
{
|
||||
name: "no taints",
|
||||
bindingSpec: &workv1alpha2.ResourceBindingSpec{
|
||||
Placement: &policyv1alpha1.Placement{},
|
||||
},
|
||||
cluster: &clusterv1alpha1.Cluster{},
|
||||
expectedCode: framework.Success,
|
||||
},
|
||||
{
|
||||
name: "tolerated taint",
|
||||
bindingSpec: &workv1alpha2.ResourceBindingSpec{
|
||||
Placement: &policyv1alpha1.Placement{
|
||||
ClusterTolerations: []corev1.Toleration{
|
||||
{
|
||||
Key: "key1",
|
||||
Operator: corev1.TolerationOpEqual,
|
||||
Value: "value1",
|
||||
Effect: corev1.TaintEffectNoSchedule,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
cluster: &clusterv1alpha1.Cluster{
|
||||
Spec: clusterv1alpha1.ClusterSpec{
|
||||
Taints: []corev1.Taint{
|
||||
{
|
||||
Key: "key1",
|
||||
Value: "value1",
|
||||
Effect: corev1.TaintEffectNoSchedule,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedCode: framework.Success,
|
||||
},
|
||||
{
|
||||
name: "untolerated taint",
|
||||
bindingSpec: &workv1alpha2.ResourceBindingSpec{
|
||||
Placement: &policyv1alpha1.Placement{},
|
||||
},
|
||||
cluster: &clusterv1alpha1.Cluster{
|
||||
Spec: clusterv1alpha1.ClusterSpec{
|
||||
Taints: []corev1.Taint{
|
||||
{
|
||||
Key: "key1",
|
||||
Value: "value1",
|
||||
Effect: corev1.TaintEffectNoSchedule,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedCode: framework.Unschedulable,
|
||||
expectedReason: "cluster(s) had untolerated taint {key1=value1:NoSchedule}",
|
||||
},
|
||||
}
|
||||
|
||||
p := &TaintToleration{}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result := p.Filter(context.Background(), tt.bindingSpec, nil, tt.cluster)
|
||||
assert.Equal(t, tt.expectedCode, result.Code())
|
||||
if tt.expectedReason != "" {
|
||||
assert.Contains(t, result.AsError().Error(), tt.expectedReason)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestNew(t *testing.T) {
|
||||
plugin, err := New()
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, plugin)
|
||||
_, ok := plugin.(*TaintToleration)
|
||||
assert.True(t, ok)
|
||||
}
|
||||
|
||||
func TestTaintToleration_Name(t *testing.T) {
|
||||
p := &TaintToleration{}
|
||||
assert.Equal(t, Name, p.Name())
|
||||
}
|
Loading…
Reference in New Issue