karmada/pkg/webhook/resourceinterpretercustomiz.../helper_test.go

494 lines
19 KiB
Go

/*
Copyright 2022 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 resourceinterpretercustomization
import (
"testing"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
configv1alpha1 "github.com/karmada-io/karmada/pkg/apis/config/v1alpha1"
)
func Test_validateCustomizationRule(t *testing.T) {
type args struct {
oldRules *configv1alpha1.ResourceInterpreterCustomization
newRules *configv1alpha1.ResourceInterpreterCustomization
}
tests := []struct {
name string
args args
wantErr bool
}{
{
name: "the different Kind of ResourceInterpreterCustomization",
args: args{
oldRules: &configv1alpha1.ResourceInterpreterCustomization{
Spec: configv1alpha1.ResourceInterpreterCustomizationSpec{
Target: configv1alpha1.CustomizationTarget{
APIVersion: "foo/v1",
Kind: "kind",
},
},
},
newRules: &configv1alpha1.ResourceInterpreterCustomization{
Spec: configv1alpha1.ResourceInterpreterCustomizationSpec{
Target: configv1alpha1.CustomizationTarget{
APIVersion: "foo/v1",
Kind: "bar",
},
},
},
},
wantErr: false,
},
{
name: " the different APIVersion of ResourceInterpreterCustomization",
args: args{
oldRules: &configv1alpha1.ResourceInterpreterCustomization{
Spec: configv1alpha1.ResourceInterpreterCustomizationSpec{
Target: configv1alpha1.CustomizationTarget{
APIVersion: "foo/v1",
Kind: "kind",
},
},
},
newRules: &configv1alpha1.ResourceInterpreterCustomization{
Spec: configv1alpha1.ResourceInterpreterCustomizationSpec{
Target: configv1alpha1.CustomizationTarget{
APIVersion: "foo/v2",
Kind: "kind",
},
},
},
},
wantErr: false,
},
{
name: "the same InterpreterOperation(Retention) of ResourceInterpreterCustomization",
args: args{
oldRules: &configv1alpha1.ResourceInterpreterCustomization{
Spec: configv1alpha1.ResourceInterpreterCustomizationSpec{
Target: configv1alpha1.CustomizationTarget{
APIVersion: "foo/v1",
Kind: "kind",
},
Customizations: configv1alpha1.CustomizationRules{
Retention: &configv1alpha1.LocalValueRetention{LuaScript: "LuaScript"},
},
},
},
newRules: &configv1alpha1.ResourceInterpreterCustomization{
Spec: configv1alpha1.ResourceInterpreterCustomizationSpec{
Target: configv1alpha1.CustomizationTarget{
APIVersion: "foo/v1",
Kind: "kind",
},
Customizations: configv1alpha1.CustomizationRules{
Retention: &configv1alpha1.LocalValueRetention{LuaScript: "LuaScript"},
},
},
},
},
wantErr: true,
},
{
name: "the same InterpreterOperation(ReplicaResource) of ResourceInterpreterCustomization",
args: args{
oldRules: &configv1alpha1.ResourceInterpreterCustomization{
Spec: configv1alpha1.ResourceInterpreterCustomizationSpec{
Target: configv1alpha1.CustomizationTarget{
APIVersion: "foo/v1",
Kind: "kind",
},
Customizations: configv1alpha1.CustomizationRules{
ReplicaResource: &configv1alpha1.ReplicaResourceRequirement{LuaScript: "LuaScript"},
},
},
},
newRules: &configv1alpha1.ResourceInterpreterCustomization{
Spec: configv1alpha1.ResourceInterpreterCustomizationSpec{
Target: configv1alpha1.CustomizationTarget{
APIVersion: "foo/v1",
Kind: "kind",
},
Customizations: configv1alpha1.CustomizationRules{
ReplicaResource: &configv1alpha1.ReplicaResourceRequirement{LuaScript: "LuaScript"},
},
},
},
},
wantErr: true,
},
{
name: "the same InterpreterOperation(ReplicaRevision) of ResourceInterpreterCustomization",
args: args{
oldRules: &configv1alpha1.ResourceInterpreterCustomization{
Spec: configv1alpha1.ResourceInterpreterCustomizationSpec{
Target: configv1alpha1.CustomizationTarget{
APIVersion: "foo/v1",
Kind: "kind",
},
Customizations: configv1alpha1.CustomizationRules{
ReplicaRevision: &configv1alpha1.ReplicaRevision{LuaScript: "LuaScript"},
},
},
},
newRules: &configv1alpha1.ResourceInterpreterCustomization{
Spec: configv1alpha1.ResourceInterpreterCustomizationSpec{
Target: configv1alpha1.CustomizationTarget{
APIVersion: "foo/v1",
Kind: "kind",
},
Customizations: configv1alpha1.CustomizationRules{
ReplicaRevision: &configv1alpha1.ReplicaRevision{LuaScript: "LuaScript"},
},
},
},
},
wantErr: true,
},
{
name: "the same InterpreterOperation(StatusReflection) of ResourceInterpreterCustomization",
args: args{
oldRules: &configv1alpha1.ResourceInterpreterCustomization{
Spec: configv1alpha1.ResourceInterpreterCustomizationSpec{
Target: configv1alpha1.CustomizationTarget{
APIVersion: "foo/v1",
Kind: "kind",
},
Customizations: configv1alpha1.CustomizationRules{
StatusReflection: &configv1alpha1.StatusReflection{LuaScript: "LuaScript"},
},
},
},
newRules: &configv1alpha1.ResourceInterpreterCustomization{
Spec: configv1alpha1.ResourceInterpreterCustomizationSpec{
Target: configv1alpha1.CustomizationTarget{
APIVersion: "foo/v1",
Kind: "kind",
},
Customizations: configv1alpha1.CustomizationRules{
StatusReflection: &configv1alpha1.StatusReflection{LuaScript: "LuaScript"},
},
},
},
},
wantErr: true,
},
{
name: "the same InterpreterOperation(StatusAggregation) of ResourceInterpreterCustomization",
args: args{
oldRules: &configv1alpha1.ResourceInterpreterCustomization{
Spec: configv1alpha1.ResourceInterpreterCustomizationSpec{
Target: configv1alpha1.CustomizationTarget{
APIVersion: "foo/v1",
Kind: "kind",
},
Customizations: configv1alpha1.CustomizationRules{
StatusAggregation: &configv1alpha1.StatusAggregation{LuaScript: "LuaScript"},
},
},
},
newRules: &configv1alpha1.ResourceInterpreterCustomization{
Spec: configv1alpha1.ResourceInterpreterCustomizationSpec{
Target: configv1alpha1.CustomizationTarget{
APIVersion: "foo/v1",
Kind: "kind",
},
Customizations: configv1alpha1.CustomizationRules{
StatusAggregation: &configv1alpha1.StatusAggregation{LuaScript: "LuaScript"},
},
},
},
},
wantErr: true,
},
{
name: "the same InterpreterOperation(HealthInterpretation) of ResourceInterpreterCustomization",
args: args{
oldRules: &configv1alpha1.ResourceInterpreterCustomization{
Spec: configv1alpha1.ResourceInterpreterCustomizationSpec{
Target: configv1alpha1.CustomizationTarget{
APIVersion: "foo/v1",
Kind: "kind",
},
Customizations: configv1alpha1.CustomizationRules{
HealthInterpretation: &configv1alpha1.HealthInterpretation{LuaScript: "LuaScript"},
},
},
},
newRules: &configv1alpha1.ResourceInterpreterCustomization{
Spec: configv1alpha1.ResourceInterpreterCustomizationSpec{
Target: configv1alpha1.CustomizationTarget{
APIVersion: "foo/v1",
Kind: "kind",
},
Customizations: configv1alpha1.CustomizationRules{
HealthInterpretation: &configv1alpha1.HealthInterpretation{LuaScript: "LuaScript"},
},
},
},
},
wantErr: true,
},
{
name: "the same InterpreterOperation(DependencyInterpretation) of ResourceInterpreterCustomization",
args: args{
oldRules: &configv1alpha1.ResourceInterpreterCustomization{
Spec: configv1alpha1.ResourceInterpreterCustomizationSpec{
Target: configv1alpha1.CustomizationTarget{
APIVersion: "foo/v1",
Kind: "kind",
},
Customizations: configv1alpha1.CustomizationRules{
DependencyInterpretation: &configv1alpha1.DependencyInterpretation{LuaScript: "LuaScript"},
},
},
},
newRules: &configv1alpha1.ResourceInterpreterCustomization{
Spec: configv1alpha1.ResourceInterpreterCustomizationSpec{
Target: configv1alpha1.CustomizationTarget{
APIVersion: "foo/v1",
Kind: "kind",
},
Customizations: configv1alpha1.CustomizationRules{
DependencyInterpretation: &configv1alpha1.DependencyInterpretation{LuaScript: "LuaScript"},
},
},
},
},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := validateCustomizationRule(tt.args.oldRules, tt.args.newRules); (err != nil) != tt.wantErr {
t.Errorf("validateCustomizationRule() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}
func Test_validateResourceInterpreterCustomizations(t *testing.T) {
type args struct {
customization *configv1alpha1.ResourceInterpreterCustomization
customizations *configv1alpha1.ResourceInterpreterCustomizationList
}
tests := []struct {
name string
args args
wantErr bool
}{
{
name: "the same name of ResourceInterpreterCustomization",
args: args{
customization: &configv1alpha1.ResourceInterpreterCustomization{
ObjectMeta: metav1.ObjectMeta{Name: "test"},
Spec: configv1alpha1.ResourceInterpreterCustomizationSpec{Target: configv1alpha1.CustomizationTarget{
APIVersion: "foo/v1",
Kind: "kind",
}, Customizations: configv1alpha1.CustomizationRules{Retention: &configv1alpha1.LocalValueRetention{LuaScript: `function Retain(desiredObj, observedObj) end`}}}},
customizations: &configv1alpha1.ResourceInterpreterCustomizationList{
Items: []configv1alpha1.ResourceInterpreterCustomization{
{ObjectMeta: metav1.ObjectMeta{Name: "test"},
Spec: configv1alpha1.ResourceInterpreterCustomizationSpec{Target: configv1alpha1.CustomizationTarget{
APIVersion: "foo/v1",
Kind: "kind",
}, Customizations: configv1alpha1.CustomizationRules{Retention: &configv1alpha1.LocalValueRetention{LuaScript: "function Retain(desiredObj, observedObj) end"}}}}}},
},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := validateResourceInterpreterCustomizations(tt.args.customization, tt.args.customizations); (err != nil) != tt.wantErr {
t.Errorf("validateResourceInterpreterCustomizations() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}
func Test_checkCustomizationsRule(t *testing.T) {
type args struct {
customization *configv1alpha1.ResourceInterpreterCustomization
}
tests := []struct {
name string
args args
wantErr bool
}{
{
name: "correct lua script",
args: args{customization: &configv1alpha1.ResourceInterpreterCustomization{
Spec: configv1alpha1.ResourceInterpreterCustomizationSpec{
Customizations: configv1alpha1.CustomizationRules{
Retention: &configv1alpha1.LocalValueRetention{LuaScript: `
function Retain(desiredObj, observedObj)
desiredObj.spec.fieldFoo = observedObj.spec.fieldFoo
return desiredObj
end
`},
ReplicaResource: &configv1alpha1.ReplicaResourceRequirement{LuaScript: `
function GetReplicas(desiredObj)
nodeClaim = {}
resourceRequest = {}
result = {}
result.replica = desiredObj.spec.replicas
result.resourceRequest = desiredObj.spec.template.spec.containers[0].resources.limits
nodeClaim.nodeSelector = desiredObj.spec.template.spec.nodeSelector
nodeClaim.tolerations = desiredObj.spec.template.spec.tolerations
result.nodeClaim = nodeClaim
return result
end
`},
ReplicaRevision: &configv1alpha1.ReplicaRevision{LuaScript: `
function ReviseReplica(desiredObj, desiredReplica)
desiredObj.spec.replicas = desiredReplica
return desiredObj
end
`},
StatusReflection: &configv1alpha1.StatusReflection{LuaScript: `
function ReflectStatus(observedObj)
status = {}
status.readyReplicas = observedObj.status.observedObj
return status
end
`},
StatusAggregation: &configv1alpha1.StatusAggregation{LuaScript: `
function AggregateStatus(desiredObj, statusItems)
for i = 1, #items do
desiredObj.status.readyReplicas = desiredObj.status.readyReplicas + items[i].readyReplicas
end
return desiredObj
end
`},
HealthInterpretation: &configv1alpha1.HealthInterpretation{LuaScript: `
function InterpretHealth(observedObj)
if observedObj.status.readyReplicas == observedObj.spec.replicas then
return true
end
end
`},
DependencyInterpretation: &configv1alpha1.DependencyInterpretation{LuaScript: `
function GetDependencies(desiredObj)
dependencies = {}
serviceAccountName = desiredObj.spec.template.spec.serviceAccountName
if serviceAccountName ~= nil and serviceAccountName ~= "default" then
dependency = {}
dependency.apiVersion = "v1"
dependency.kind = "ServiceAccount"
dependency.name = serviceAccountName
dependency.namespace = desiredObj.metadata.namespace
dependencies[1] = dependency
end
return dependencies
end
`}},
},
},
},
wantErr: false,
},
{
name: "Retention contains the wrong lua script",
args: args{customization: &configv1alpha1.ResourceInterpreterCustomization{
Spec: configv1alpha1.ResourceInterpreterCustomizationSpec{
Customizations: configv1alpha1.CustomizationRules{
Retention: &configv1alpha1.LocalValueRetention{LuaScript: `function Retain(desiredObj, observedObj)`},
},
},
}},
wantErr: true,
},
{
name: "ReplicaResource contains the wrong lua script",
args: args{customization: &configv1alpha1.ResourceInterpreterCustomization{
Spec: configv1alpha1.ResourceInterpreterCustomizationSpec{
Customizations: configv1alpha1.CustomizationRules{
ReplicaResource: &configv1alpha1.ReplicaResourceRequirement{LuaScript: `function GetReplicas(desiredObj)`},
},
},
}},
wantErr: true,
},
{
name: "ReplicaRevision contains the wrong lua script",
args: args{customization: &configv1alpha1.ResourceInterpreterCustomization{
Spec: configv1alpha1.ResourceInterpreterCustomizationSpec{
Customizations: configv1alpha1.CustomizationRules{
ReplicaRevision: &configv1alpha1.ReplicaRevision{LuaScript: `function ReviseReplica(desiredObj, desiredReplica)`}},
},
}},
wantErr: true,
},
{
name: "StatusReflection contains the wrong lua script",
args: args{customization: &configv1alpha1.ResourceInterpreterCustomization{
Spec: configv1alpha1.ResourceInterpreterCustomizationSpec{
Customizations: configv1alpha1.CustomizationRules{
StatusReflection: &configv1alpha1.StatusReflection{LuaScript: `function ReflectStatus(observedObj)`}},
},
}},
wantErr: true,
},
{
name: "StatusAggregation contains the wrong lua script",
args: args{customization: &configv1alpha1.ResourceInterpreterCustomization{
Spec: configv1alpha1.ResourceInterpreterCustomizationSpec{
Customizations: configv1alpha1.CustomizationRules{
StatusAggregation: &configv1alpha1.StatusAggregation{LuaScript: `function AggregateStatus(desiredObj, statusItems)`}},
},
}},
wantErr: true,
},
{
name: "HealthInterpretation contains the wrong lua script",
args: args{customization: &configv1alpha1.ResourceInterpreterCustomization{
Spec: configv1alpha1.ResourceInterpreterCustomizationSpec{
Customizations: configv1alpha1.CustomizationRules{
HealthInterpretation: &configv1alpha1.HealthInterpretation{LuaScript: `function InterpretHealth(observedObj)`}},
},
}},
wantErr: true,
},
{
name: "DependencyInterpretation contains the wrong lua script",
args: args{customization: &configv1alpha1.ResourceInterpreterCustomization{
Spec: configv1alpha1.ResourceInterpreterCustomizationSpec{
Customizations: configv1alpha1.CustomizationRules{
DependencyInterpretation: &configv1alpha1.DependencyInterpretation{LuaScript: `function GetDependencies(desiredObj)`}},
},
}},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := checkCustomizationsRule(tt.args.customization); (err != nil) != tt.wantErr {
t.Errorf("checkCustomizationsRule() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}