392 lines
10 KiB
Go
392 lines
10 KiB
Go
package helper
|
|
|
|
import (
|
|
"context"
|
|
"reflect"
|
|
"testing"
|
|
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"k8s.io/utils/pointer"
|
|
"sigs.k8s.io/controller-runtime/pkg/client/fake"
|
|
|
|
policyv1alpha1 "github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1"
|
|
"github.com/karmada-io/karmada/pkg/util"
|
|
)
|
|
|
|
func TestSetDefaultSpreadConstraints(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
spreadConstraint []policyv1alpha1.SpreadConstraint
|
|
expectedSpreadConstraint []policyv1alpha1.SpreadConstraint
|
|
}{
|
|
{
|
|
name: "set spreadByField",
|
|
spreadConstraint: []policyv1alpha1.SpreadConstraint{
|
|
{
|
|
MinGroups: 1,
|
|
},
|
|
},
|
|
expectedSpreadConstraint: []policyv1alpha1.SpreadConstraint{
|
|
{
|
|
SpreadByField: policyv1alpha1.SpreadByFieldCluster,
|
|
MinGroups: 1,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "set minGroups",
|
|
spreadConstraint: []policyv1alpha1.SpreadConstraint{
|
|
{
|
|
SpreadByField: policyv1alpha1.SpreadByFieldCluster,
|
|
},
|
|
},
|
|
expectedSpreadConstraint: []policyv1alpha1.SpreadConstraint{
|
|
{
|
|
SpreadByField: policyv1alpha1.SpreadByFieldCluster,
|
|
MinGroups: 1,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
SetDefaultSpreadConstraints(tt.spreadConstraint)
|
|
if !reflect.DeepEqual(tt.spreadConstraint, tt.expectedSpreadConstraint) {
|
|
t.Errorf("expected: %v, but got %v", tt.expectedSpreadConstraint, tt.spreadConstraint)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestIsDependentOverridesPresent(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
policy *policyv1alpha1.PropagationPolicy
|
|
policyCreated bool
|
|
expectedExist bool
|
|
}{
|
|
{
|
|
name: "dependent override policy exist",
|
|
policy: &policyv1alpha1.PropagationPolicy{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "foo",
|
|
Namespace: "bar",
|
|
},
|
|
Spec: policyv1alpha1.PropagationSpec{
|
|
DependentOverrides: []string{"foo"},
|
|
},
|
|
},
|
|
policyCreated: true,
|
|
expectedExist: true,
|
|
},
|
|
{
|
|
name: "dependent override policy do not exist",
|
|
policy: &policyv1alpha1.PropagationPolicy{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "foo",
|
|
Namespace: "bar",
|
|
},
|
|
Spec: policyv1alpha1.PropagationSpec{
|
|
DependentOverrides: []string{"foo"},
|
|
},
|
|
},
|
|
policyCreated: false,
|
|
expectedExist: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
fakeClient := fake.NewClientBuilder().WithScheme(Schema).Build()
|
|
if tt.policyCreated {
|
|
testOverridePolicy := &policyv1alpha1.OverridePolicy{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Namespace: tt.policy.Namespace,
|
|
Name: tt.policy.Name,
|
|
},
|
|
}
|
|
err := fakeClient.Create(context.TODO(), testOverridePolicy)
|
|
if err != nil {
|
|
t.Fatalf("failed to create overridePolicy, err is: %v", err)
|
|
}
|
|
}
|
|
res, err := IsDependentOverridesPresent(fakeClient, tt.policy)
|
|
if !reflect.DeepEqual(res, tt.expectedExist) || err != nil {
|
|
t.Errorf("expected %v, but got %v", tt.expectedExist, res)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestIsDependentClusterOverridesPresent(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
policy *policyv1alpha1.ClusterPropagationPolicy
|
|
policyCreated bool
|
|
expectedExist bool
|
|
}{
|
|
{
|
|
name: "dependent cluster override policy exist",
|
|
policy: &policyv1alpha1.ClusterPropagationPolicy{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "foo",
|
|
},
|
|
Spec: policyv1alpha1.PropagationSpec{
|
|
DependentOverrides: []string{"foo"},
|
|
},
|
|
},
|
|
policyCreated: true,
|
|
expectedExist: true,
|
|
},
|
|
{
|
|
name: "dependent cluster override policy do not exist",
|
|
policy: &policyv1alpha1.ClusterPropagationPolicy{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "foo",
|
|
},
|
|
Spec: policyv1alpha1.PropagationSpec{
|
|
DependentOverrides: []string{"foo"},
|
|
},
|
|
},
|
|
policyCreated: false,
|
|
expectedExist: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
fakeClient := fake.NewClientBuilder().WithScheme(Schema).Build()
|
|
if tt.policyCreated {
|
|
testClusterOverridePolicy := &policyv1alpha1.ClusterOverridePolicy{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: tt.policy.Name,
|
|
},
|
|
}
|
|
err := fakeClient.Create(context.TODO(), testClusterOverridePolicy)
|
|
if err != nil {
|
|
t.Fatalf("failed to create clusterOverridePolicy, err is: %v", err)
|
|
}
|
|
}
|
|
res, err := IsDependentClusterOverridesPresent(fakeClient, tt.policy)
|
|
if !reflect.DeepEqual(res, tt.expectedExist) || err != nil {
|
|
t.Errorf("expected %v, but got %v", tt.expectedExist, res)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCheckMatchServiceImport(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
resourceSelectors []policyv1alpha1.ResourceSelector
|
|
expected bool
|
|
}{
|
|
{
|
|
name: " get followed resource selector",
|
|
resourceSelectors: []policyv1alpha1.ResourceSelector{
|
|
{
|
|
Name: "foo1",
|
|
Kind: util.ServiceImportKind,
|
|
},
|
|
{
|
|
Name: "foo2",
|
|
Namespace: "bar",
|
|
Kind: util.ServiceKind,
|
|
},
|
|
{
|
|
Name: "foo3",
|
|
Namespace: "bar",
|
|
Kind: util.ServiceImportKind,
|
|
APIVersion: "multicluster.x-k8s.io/v1alpha1",
|
|
},
|
|
},
|
|
expected: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
res := ContainsServiceImport(tt.resourceSelectors)
|
|
if !reflect.DeepEqual(res, tt.expected) {
|
|
t.Errorf("expected %v, but got %v", tt.expected, res)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestIsReplicaDynamicDivided(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
strategy *policyv1alpha1.ReplicaSchedulingStrategy
|
|
expected bool
|
|
}{
|
|
{
|
|
name: "strategy empty",
|
|
strategy: nil,
|
|
expected: false,
|
|
},
|
|
{
|
|
name: "strategy duplicated",
|
|
strategy: &policyv1alpha1.ReplicaSchedulingStrategy{
|
|
ReplicaSchedulingType: policyv1alpha1.ReplicaSchedulingTypeDuplicated,
|
|
},
|
|
expected: false,
|
|
},
|
|
{
|
|
name: "strategy division preference weighted",
|
|
strategy: &policyv1alpha1.ReplicaSchedulingStrategy{
|
|
ReplicaDivisionPreference: policyv1alpha1.ReplicaDivisionPreferenceWeighted,
|
|
ReplicaSchedulingType: policyv1alpha1.ReplicaSchedulingTypeDivided,
|
|
WeightPreference: &policyv1alpha1.ClusterPreferences{
|
|
DynamicWeight: policyv1alpha1.DynamicWeightByAvailableReplicas,
|
|
},
|
|
},
|
|
expected: true,
|
|
},
|
|
{
|
|
name: "strategy division preference aggregated",
|
|
strategy: &policyv1alpha1.ReplicaSchedulingStrategy{
|
|
ReplicaSchedulingType: policyv1alpha1.ReplicaSchedulingTypeDivided,
|
|
ReplicaDivisionPreference: policyv1alpha1.ReplicaDivisionPreferenceAggregated,
|
|
},
|
|
expected: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
res := IsReplicaDynamicDivided(&policyv1alpha1.Placement{ReplicaScheduling: tt.strategy})
|
|
if res != tt.expected {
|
|
t.Errorf("expected %v, but got %v", tt.expected, res)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGetAppliedPlacement(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
annotations map[string]string
|
|
expectedPlacement *policyv1alpha1.Placement
|
|
expectedErr error
|
|
}{
|
|
{
|
|
name: "policy placement annotation exist",
|
|
annotations: map[string]string{
|
|
util.PolicyPlacementAnnotation: "{\"clusterAffinity\":{\"clusterNames\":[\"member1\",\"member2\"]}}",
|
|
},
|
|
expectedPlacement: &policyv1alpha1.Placement{
|
|
ClusterAffinity: &policyv1alpha1.ClusterAffinity{
|
|
ClusterNames: []string{"member1", "member2"},
|
|
},
|
|
},
|
|
expectedErr: nil,
|
|
},
|
|
{
|
|
name: "policy placement annotation do not exist",
|
|
annotations: map[string]string{
|
|
"foo": "bar",
|
|
},
|
|
expectedPlacement: nil,
|
|
expectedErr: nil,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
res, err := GetAppliedPlacement(tt.annotations)
|
|
if !reflect.DeepEqual(res, tt.expectedPlacement) || err != tt.expectedErr {
|
|
t.Errorf("expected %v and %v, but got %v and %v", tt.expectedPlacement, tt.expectedErr, res, err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSetReplicaDivisionPreferenceWeighted(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
strategy *policyv1alpha1.ReplicaSchedulingStrategy
|
|
expectedWeighted bool
|
|
}{
|
|
{
|
|
name: "no replica scheduling strategy declared",
|
|
expectedWeighted: false,
|
|
},
|
|
{
|
|
name: "specified aggregated division preference",
|
|
strategy: &policyv1alpha1.ReplicaSchedulingStrategy{
|
|
ReplicaSchedulingType: policyv1alpha1.ReplicaSchedulingTypeDivided,
|
|
ReplicaDivisionPreference: policyv1alpha1.ReplicaDivisionPreferenceAggregated,
|
|
},
|
|
expectedWeighted: false,
|
|
},
|
|
{
|
|
name: "unspecified replica division preference",
|
|
strategy: &policyv1alpha1.ReplicaSchedulingStrategy{
|
|
ReplicaSchedulingType: policyv1alpha1.ReplicaSchedulingTypeDivided,
|
|
},
|
|
expectedWeighted: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
p := &policyv1alpha1.Placement{ReplicaScheduling: tt.strategy}
|
|
SetReplicaDivisionPreferenceWeighted(p)
|
|
if (p.ReplicaScheduling != nil &&
|
|
p.ReplicaScheduling.ReplicaDivisionPreference == policyv1alpha1.ReplicaDivisionPreferenceWeighted) != tt.expectedWeighted {
|
|
t.Errorf("expectedWeighted %v, but got %v", tt.expectedWeighted, !tt.expectedWeighted)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSetDefaultGracePeriodSeconds(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
behavior *policyv1alpha1.ApplicationFailoverBehavior
|
|
expectBehavior *policyv1alpha1.ApplicationFailoverBehavior
|
|
}{
|
|
{
|
|
name: "purgeMode is not graciously",
|
|
behavior: &policyv1alpha1.ApplicationFailoverBehavior{
|
|
PurgeMode: policyv1alpha1.Never,
|
|
},
|
|
expectBehavior: &policyv1alpha1.ApplicationFailoverBehavior{
|
|
PurgeMode: policyv1alpha1.Never,
|
|
},
|
|
},
|
|
{
|
|
name: "purgeMode is graciously and gracePeriodSeconds is set",
|
|
behavior: &policyv1alpha1.ApplicationFailoverBehavior{
|
|
PurgeMode: policyv1alpha1.Graciously,
|
|
GracePeriodSeconds: pointer.Int32(200),
|
|
},
|
|
expectBehavior: &policyv1alpha1.ApplicationFailoverBehavior{
|
|
PurgeMode: policyv1alpha1.Graciously,
|
|
GracePeriodSeconds: pointer.Int32(200),
|
|
},
|
|
},
|
|
{
|
|
name: "purgeMode is graciously and gracePeriodSeconds is not set",
|
|
behavior: &policyv1alpha1.ApplicationFailoverBehavior{
|
|
PurgeMode: policyv1alpha1.Graciously,
|
|
},
|
|
expectBehavior: &policyv1alpha1.ApplicationFailoverBehavior{
|
|
PurgeMode: policyv1alpha1.Graciously,
|
|
GracePeriodSeconds: pointer.Int32(600),
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
SetDefaultGracePeriodSeconds(tt.behavior)
|
|
if !reflect.DeepEqual(tt.behavior, tt.expectBehavior) {
|
|
t.Errorf("expectedBehavior %v, but got %v", tt.expectBehavior, tt.behavior)
|
|
}
|
|
})
|
|
}
|
|
}
|