Merge pull request #3395 from realnumber666/add-unit-test
Add UT for workstatus.go and taint.go and rule.go
This commit is contained in:
commit
2ef01942f1
|
@ -2,15 +2,19 @@ package helper
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
fakeclient "sigs.k8s.io/controller-runtime/pkg/client/fake"
|
||||
|
||||
clusterv1alpha1 "github.com/karmada-io/karmada/pkg/apis/cluster/v1alpha1"
|
||||
policyv1alpha1 "github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1"
|
||||
"github.com/karmada-io/karmada/pkg/util/gclient"
|
||||
)
|
||||
|
||||
|
@ -98,6 +102,16 @@ func TestUpdateClusterControllerTaint(t *testing.T) {
|
|||
wantTaints: []corev1.Taint{*notReadyTaintTemplate},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "clusterTaintsToAdd is nil and clusterTaintsToRemove is nil",
|
||||
args: args{
|
||||
taints: []corev1.Taint{*unreachableTaintTemplate},
|
||||
taintsToAdd: []*corev1.Taint{unreachableTaintTemplate.DeepCopy()},
|
||||
taintsToRemove: []*corev1.Taint{notReadyTaintTemplate.DeepCopy()},
|
||||
},
|
||||
wantTaints: []corev1.Taint{*unreachableTaintTemplate},
|
||||
wantErr: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
@ -266,6 +280,31 @@ func TestTolerationExists(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestAddTolerations(t *testing.T) {
|
||||
placement := &policyv1alpha1.Placement{
|
||||
ClusterTolerations: []corev1.Toleration{},
|
||||
}
|
||||
|
||||
toleration1 := &corev1.Toleration{
|
||||
Key: "key1",
|
||||
Operator: corev1.TolerationOpEqual,
|
||||
Value: "value1",
|
||||
Effect: corev1.TaintEffectNoSchedule,
|
||||
}
|
||||
toleration2 := &corev1.Toleration{
|
||||
Key: "key2",
|
||||
Operator: corev1.TolerationOpEqual,
|
||||
Value: "value2",
|
||||
Effect: corev1.TaintEffectNoSchedule,
|
||||
}
|
||||
|
||||
AddTolerations(placement, toleration1, toleration2)
|
||||
|
||||
assert.Equal(t, 2, len(placement.ClusterTolerations))
|
||||
assert.Equal(t, *toleration1, placement.ClusterTolerations[0])
|
||||
assert.Equal(t, *toleration2, placement.ClusterTolerations[1])
|
||||
}
|
||||
|
||||
func TestHasNoExecuteTaints(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
|
@ -357,3 +396,319 @@ func TestGetNoExecuteTaints(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetMinTolerationTime(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
noExecuteTaints []corev1.Taint
|
||||
usedTolerantion []corev1.Toleration
|
||||
wantResult time.Duration
|
||||
}{
|
||||
{
|
||||
name: "no noExecuteTaints",
|
||||
noExecuteTaints: []corev1.Taint{},
|
||||
usedTolerantion: []corev1.Toleration{
|
||||
{
|
||||
Key: "key",
|
||||
Operator: corev1.TolerationOpExists,
|
||||
Effect: corev1.TaintEffectNoExecute,
|
||||
TolerationSeconds: &[]int64{60}[0],
|
||||
},
|
||||
},
|
||||
wantResult: -1,
|
||||
},
|
||||
{
|
||||
name: "no usedTolerations",
|
||||
noExecuteTaints: []corev1.Taint{
|
||||
{
|
||||
Key: "key",
|
||||
Value: "value",
|
||||
Effect: corev1.TaintEffectNoExecute,
|
||||
TimeAdded: &metav1.Time{Time: time.Now()},
|
||||
},
|
||||
},
|
||||
usedTolerantion: []corev1.Toleration{},
|
||||
wantResult: 0,
|
||||
},
|
||||
{
|
||||
name: "with noExecuteTaints and usedTolerations",
|
||||
noExecuteTaints: []corev1.Taint{
|
||||
{
|
||||
Key: "key",
|
||||
Value: "value",
|
||||
Effect: corev1.TaintEffectNoExecute,
|
||||
TimeAdded: &metav1.Time{Time: time.Now()},
|
||||
},
|
||||
},
|
||||
usedTolerantion: []corev1.Toleration{
|
||||
{
|
||||
Key: "key",
|
||||
Operator: corev1.TolerationOpExists,
|
||||
Effect: corev1.TaintEffectNoExecute,
|
||||
TolerationSeconds: &[]int64{60}[0],
|
||||
},
|
||||
},
|
||||
wantResult: 60,
|
||||
},
|
||||
{
|
||||
name: "usedTolerantion.TolerationSeconds is nil",
|
||||
noExecuteTaints: []corev1.Taint{
|
||||
{
|
||||
Key: "key",
|
||||
Value: "value",
|
||||
Effect: corev1.TaintEffectNoExecute,
|
||||
TimeAdded: &metav1.Time{Time: time.Now()},
|
||||
},
|
||||
},
|
||||
usedTolerantion: []corev1.Toleration{
|
||||
{
|
||||
Key: "key",
|
||||
Operator: corev1.TolerationOpExists,
|
||||
Effect: corev1.TaintEffectNoExecute,
|
||||
TolerationSeconds: nil,
|
||||
},
|
||||
},
|
||||
wantResult: -1,
|
||||
},
|
||||
{
|
||||
name: "noExecuteTaints.TimeAdded is nil",
|
||||
noExecuteTaints: []corev1.Taint{
|
||||
{
|
||||
Key: "key",
|
||||
Value: "value",
|
||||
Effect: corev1.TaintEffectNoExecute,
|
||||
TimeAdded: nil,
|
||||
},
|
||||
},
|
||||
usedTolerantion: []corev1.Toleration{
|
||||
{
|
||||
Key: "key",
|
||||
Operator: corev1.TolerationOpExists,
|
||||
Effect: corev1.TaintEffectNoExecute,
|
||||
TolerationSeconds: &[]int64{60}[0],
|
||||
},
|
||||
},
|
||||
wantResult: -1,
|
||||
},
|
||||
{
|
||||
name: "find the latest trigger time",
|
||||
noExecuteTaints: []corev1.Taint{
|
||||
{
|
||||
Key: "key1",
|
||||
Value: "value1",
|
||||
Effect: corev1.TaintEffectNoExecute,
|
||||
TimeAdded: &metav1.Time{Time: time.Now()},
|
||||
},
|
||||
{
|
||||
Key: "key2",
|
||||
Value: "value2",
|
||||
Effect: corev1.TaintEffectNoExecute,
|
||||
TimeAdded: &metav1.Time{Time: time.Now()},
|
||||
},
|
||||
},
|
||||
usedTolerantion: []corev1.Toleration{
|
||||
{
|
||||
Key: "key1",
|
||||
Operator: corev1.TolerationOpExists,
|
||||
Effect: corev1.TaintEffectNoExecute,
|
||||
TolerationSeconds: &[]int64{120}[0],
|
||||
},
|
||||
{
|
||||
Key: "key2",
|
||||
Operator: corev1.TolerationOpExists,
|
||||
Effect: corev1.TaintEffectNoExecute,
|
||||
TolerationSeconds: &[]int64{60}[0],
|
||||
},
|
||||
},
|
||||
wantResult: 60,
|
||||
},
|
||||
{
|
||||
name: "trigger time is up",
|
||||
noExecuteTaints: []corev1.Taint{
|
||||
{
|
||||
Key: "key",
|
||||
Value: "value",
|
||||
Effect: corev1.TaintEffectNoExecute,
|
||||
TimeAdded: &metav1.Time{
|
||||
Time: time.Now().Add(-time.Hour),
|
||||
},
|
||||
},
|
||||
},
|
||||
usedTolerantion: []corev1.Toleration{
|
||||
{
|
||||
Key: "key",
|
||||
Operator: corev1.TolerationOpExists,
|
||||
Effect: corev1.TaintEffectNoExecute,
|
||||
TolerationSeconds: &[]int64{60}[0],
|
||||
},
|
||||
},
|
||||
wantResult: 0,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result := GetMinTolerationTime(tt.noExecuteTaints, tt.usedTolerantion)
|
||||
fmt.Printf("%+v", result)
|
||||
if result > 0 {
|
||||
if result > (tt.wantResult+1)*time.Second || result < (tt.wantResult-1)*time.Second {
|
||||
t.Errorf("GetMinTolerationTime() = %v, want %v", result, tt.wantResult)
|
||||
}
|
||||
} else if result != tt.wantResult {
|
||||
t.Errorf("GetMinTolerationTime() = %v, want %v", result, tt.wantResult)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetMatchingTolerations(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
taints []corev1.Taint
|
||||
tolerations []corev1.Toleration
|
||||
wantActual bool
|
||||
wantActualTolerations []corev1.Toleration
|
||||
}{
|
||||
{
|
||||
name: "taints is nil",
|
||||
taints: []corev1.Taint{},
|
||||
tolerations: []corev1.Toleration{
|
||||
{
|
||||
Key: "key1",
|
||||
Value: "value1",
|
||||
Effect: corev1.TaintEffectNoSchedule,
|
||||
},
|
||||
},
|
||||
wantActual: true,
|
||||
wantActualTolerations: []corev1.Toleration{},
|
||||
},
|
||||
{
|
||||
name: "tolerations is nil",
|
||||
taints: []corev1.Taint{
|
||||
{
|
||||
Key: "key1",
|
||||
Value: "value1",
|
||||
Effect: corev1.TaintEffectNoSchedule,
|
||||
},
|
||||
},
|
||||
tolerations: []corev1.Toleration{},
|
||||
wantActual: false,
|
||||
wantActualTolerations: []corev1.Toleration{},
|
||||
},
|
||||
{
|
||||
name: "tolerated is true",
|
||||
taints: []corev1.Taint{
|
||||
{
|
||||
Key: "key1",
|
||||
Value: "value1",
|
||||
Effect: corev1.TaintEffectNoSchedule,
|
||||
},
|
||||
{
|
||||
Key: "key2",
|
||||
Value: "value2",
|
||||
Effect: corev1.TaintEffectNoSchedule,
|
||||
},
|
||||
},
|
||||
tolerations: []corev1.Toleration{
|
||||
{
|
||||
Key: "key1",
|
||||
Value: "value1",
|
||||
Effect: corev1.TaintEffectNoSchedule,
|
||||
},
|
||||
{
|
||||
Key: "key2",
|
||||
Value: "value2",
|
||||
Effect: corev1.TaintEffectNoSchedule,
|
||||
},
|
||||
},
|
||||
wantActual: true,
|
||||
wantActualTolerations: []corev1.Toleration{
|
||||
{
|
||||
Key: "key1",
|
||||
Value: "value1",
|
||||
Effect: corev1.TaintEffectNoSchedule,
|
||||
},
|
||||
{
|
||||
Key: "key2",
|
||||
Value: "value2",
|
||||
Effect: corev1.TaintEffectNoSchedule,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "tolerated is false",
|
||||
taints: []corev1.Taint{
|
||||
{
|
||||
Key: "key1",
|
||||
Value: "value1",
|
||||
Effect: corev1.TaintEffectNoSchedule,
|
||||
},
|
||||
{
|
||||
Key: "key2",
|
||||
Value: "value2",
|
||||
Effect: corev1.TaintEffectNoSchedule,
|
||||
},
|
||||
},
|
||||
tolerations: []corev1.Toleration{
|
||||
{
|
||||
Key: "key1",
|
||||
Value: "value_1",
|
||||
Effect: corev1.TaintEffectNoSchedule,
|
||||
},
|
||||
{
|
||||
Key: "key2",
|
||||
Value: "value_2",
|
||||
Effect: corev1.TaintEffectNoSchedule,
|
||||
},
|
||||
},
|
||||
wantActual: false,
|
||||
wantActualTolerations: []corev1.Toleration{},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
actual, actualTolerations := GetMatchingTolerations(tt.taints, tt.tolerations)
|
||||
if actual != tt.wantActual || !reflect.DeepEqual(actualTolerations, tt.wantActualTolerations) {
|
||||
t.Errorf("GetMatchingTolerations(%v, %v) = (%v, %v), expected (%v, %v)", tt.taints, tt.tolerations, actual, actualTolerations, tt.wantActual, tt.wantActualTolerations)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewNotReadyToleration(t *testing.T) {
|
||||
expectedKey := clusterv1alpha1.TaintClusterNotReady
|
||||
expectedOperator := corev1.TolerationOpExists
|
||||
expectedEffect := corev1.TaintEffectNoExecute
|
||||
expectedSeconds := int64(123)
|
||||
|
||||
toleration := NewNotReadyToleration(expectedSeconds)
|
||||
|
||||
if toleration.Key != expectedKey {
|
||||
t.Errorf("Expected key %q but got %q", expectedKey, toleration.Key)
|
||||
}
|
||||
if toleration.Operator != expectedOperator {
|
||||
t.Errorf("Expected operator %q but got %q", expectedOperator, toleration.Operator)
|
||||
}
|
||||
if toleration.Effect != expectedEffect {
|
||||
t.Errorf("Expected effect %q but got %q", expectedEffect, toleration.Effect)
|
||||
}
|
||||
if *toleration.TolerationSeconds != expectedSeconds {
|
||||
t.Errorf("Expected seconds %d but got %d", expectedSeconds, *toleration.TolerationSeconds)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewUnreachableToleration(t *testing.T) {
|
||||
tolerationSeconds := int64(300)
|
||||
expectedToleration := &corev1.Toleration{
|
||||
Key: clusterv1alpha1.TaintClusterUnreachable,
|
||||
Operator: corev1.TolerationOpExists,
|
||||
Effect: corev1.TaintEffectNoExecute,
|
||||
TolerationSeconds: &tolerationSeconds,
|
||||
}
|
||||
|
||||
actualToleration := NewUnreachableToleration(tolerationSeconds)
|
||||
|
||||
if !reflect.DeepEqual(actualToleration, expectedToleration) {
|
||||
t.Errorf("NewUnreachableToleration() = %v, want %v", actualToleration, expectedToleration)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,11 +3,42 @@ package helper
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
|
||||
workv1alpha1 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha1"
|
||||
workv1alpha2 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha2"
|
||||
)
|
||||
|
||||
func TestGenerateFullyAppliedCondition(t *testing.T) {
|
||||
spec := workv1alpha2.ResourceBindingSpec{
|
||||
Clusters: []workv1alpha2.TargetCluster{
|
||||
{Name: "cluster1"},
|
||||
{Name: "cluster2"},
|
||||
},
|
||||
}
|
||||
statuses := []workv1alpha2.AggregatedStatusItem{
|
||||
{ClusterName: "cluster1", Applied: true, Health: workv1alpha2.ResourceHealthy},
|
||||
{ClusterName: "cluster2", Applied: true, Health: workv1alpha2.ResourceUnknown},
|
||||
}
|
||||
|
||||
expectedTrue := metav1.ConditionTrue
|
||||
expectedFalse := metav1.ConditionFalse
|
||||
|
||||
resultTrue := generateFullyAppliedCondition(spec, statuses)
|
||||
if resultTrue.Status != expectedTrue {
|
||||
t.Errorf("generateFullyAppliedCondition with fully applied statuses returned %v, expected %v", resultTrue, expectedTrue)
|
||||
}
|
||||
|
||||
resultFalse := generateFullyAppliedCondition(spec, statuses[:1])
|
||||
if resultFalse.Status != expectedFalse {
|
||||
t.Errorf("generateFullyAppliedCondition with partially applied statuses returned %v, expected %v", resultFalse, expectedFalse)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWorksFullyApplied(t *testing.T) {
|
||||
type args struct {
|
||||
aggregatedStatuses []workv1alpha2.AggregatedStatusItem
|
||||
|
@ -108,3 +139,150 @@ func TestWorksFullyApplied(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetManifestIndex(t *testing.T) {
|
||||
manifest1 := workv1alpha1.Manifest{
|
||||
RawExtension: runtime.RawExtension{
|
||||
Raw: []byte(`{"apiVersion":"v1","kind":"Service","metadata":{"name":"test-service","namespace":"test-namespace"}}`),
|
||||
},
|
||||
}
|
||||
manifest2 := workv1alpha1.Manifest{
|
||||
RawExtension: runtime.RawExtension{
|
||||
Raw: []byte(`{"apiVersion":"apps/v1","kind":"Deployment","metadata":{"name":"test-deployment","namespace":"test-namespace"}}`),
|
||||
},
|
||||
}
|
||||
manifests := []workv1alpha1.Manifest{manifest1, manifest2}
|
||||
|
||||
service := &unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Service",
|
||||
"metadata": map[string]interface{}{
|
||||
"name": "test-service",
|
||||
"namespace": "test-namespace",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
deployment := &unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"apiVersion": "apps/v1",
|
||||
"kind": "Deployment",
|
||||
"metadata": map[string]interface{}{
|
||||
"name": "test-deployment",
|
||||
"namespace": "test-namespace",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
t.Run("Service", func(t *testing.T) {
|
||||
index, err := GetManifestIndex(manifests, service)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
if index != 0 {
|
||||
t.Errorf("expected index 0, got %d", index)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Deployment", func(t *testing.T) {
|
||||
index, err := GetManifestIndex(manifests, deployment)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
if index != 1 {
|
||||
t.Errorf("expected index 1, got %d", index)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("No match", func(t *testing.T) {
|
||||
_, err := GetManifestIndex(manifests, &unstructured.Unstructured{})
|
||||
if err == nil {
|
||||
t.Errorf("expected error, got nil")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestEqualIdentifier(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
target *workv1alpha1.ResourceIdentifier
|
||||
ordinal int
|
||||
workload *unstructured.Unstructured
|
||||
expectedOutput bool
|
||||
}{
|
||||
{
|
||||
name: "identifiers are equal",
|
||||
target: &workv1alpha1.ResourceIdentifier{
|
||||
Ordinal: 0,
|
||||
Group: "apps",
|
||||
Version: "v1",
|
||||
Kind: "Deployment",
|
||||
Namespace: "default",
|
||||
Name: "test-deployment",
|
||||
},
|
||||
ordinal: 0,
|
||||
workload: &unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"apiVersion": "apps/v1",
|
||||
"kind": "Deployment",
|
||||
"metadata": map[string]interface{}{
|
||||
"namespace": "default",
|
||||
"name": "test-deployment",
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedOutput: true,
|
||||
},
|
||||
{
|
||||
name: "identifiers are not equal",
|
||||
target: &workv1alpha1.ResourceIdentifier{
|
||||
Ordinal: 1,
|
||||
Group: "apps",
|
||||
Version: "v1",
|
||||
Kind: "Deployment",
|
||||
Namespace: "default",
|
||||
Name: "test-deployment",
|
||||
},
|
||||
ordinal: 0,
|
||||
workload: &unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"apiVersion": "apps/v1",
|
||||
"kind": "Deployment",
|
||||
"metadata": map[string]interface{}{
|
||||
"namespace": "default",
|
||||
"name": "test-deployment",
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedOutput: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
equal, err := equalIdentifier(tc.target, tc.ordinal, tc.workload)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
if equal != tc.expectedOutput {
|
||||
t.Errorf("expected %v, got %v", tc.expectedOutput, equal)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsResourceApplied(t *testing.T) {
|
||||
// Create a WorkStatus struct with a WorkApplied condition set to True
|
||||
workStatus := &workv1alpha1.WorkStatus{
|
||||
Conditions: []metav1.Condition{
|
||||
{
|
||||
Type: workv1alpha1.WorkApplied,
|
||||
Status: metav1.ConditionTrue,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// Call IsResourceApplied and assert that it returns true
|
||||
assert.True(t, IsResourceApplied(workStatus))
|
||||
}
|
||||
|
|
|
@ -0,0 +1,828 @@
|
|||
package interpreter
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
|
||||
configv1alpha1 "github.com/karmada-io/karmada/pkg/apis/config/v1alpha1"
|
||||
)
|
||||
|
||||
func TestRetentionRule_Name(t *testing.T) {
|
||||
r := &retentionRule{}
|
||||
expected := string(configv1alpha1.InterpreterOperationRetain)
|
||||
actual := r.Name()
|
||||
assert.Equal(t, expected, actual, "Name should return %v", expected)
|
||||
}
|
||||
|
||||
func TestRetentionRule_Document(t *testing.T) {
|
||||
rule := &retentionRule{}
|
||||
expected := `This rule is used to retain runtime values to the desired specification.
|
||||
The script should implement a function as follows:
|
||||
function Retain(desiredObj, observedObj)
|
||||
desiredObj.spec.fieldFoo = observedObj.spec.fieldFoo
|
||||
return desiredObj
|
||||
end`
|
||||
assert.Equal(t, expected, rule.Document())
|
||||
}
|
||||
|
||||
func TestRetentionRule_GetScript(t *testing.T) {
|
||||
t.Run("WithScript", func(t *testing.T) {
|
||||
customization := &configv1alpha1.ResourceInterpreterCustomization{
|
||||
Spec: configv1alpha1.ResourceInterpreterCustomizationSpec{
|
||||
Customizations: configv1alpha1.CustomizationRules{
|
||||
Retention: &configv1alpha1.LocalValueRetention{
|
||||
LuaScript: "hello world",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
rule := &retentionRule{}
|
||||
script := rule.GetScript(customization)
|
||||
|
||||
expectedScript := customization.Spec.Customizations.Retention.LuaScript
|
||||
if script != expectedScript {
|
||||
t.Errorf("GetScript() returned %q, expected %q", script, expectedScript)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("WithoutScript", func(t *testing.T) {
|
||||
customization := &configv1alpha1.ResourceInterpreterCustomization{
|
||||
Spec: configv1alpha1.ResourceInterpreterCustomizationSpec{
|
||||
Customizations: configv1alpha1.CustomizationRules{
|
||||
Retention: nil,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
rule := &retentionRule{}
|
||||
script := rule.GetScript(customization)
|
||||
|
||||
if script != "" {
|
||||
t.Errorf("GetScript() returned %q, expected an empty string", script)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestRetentionRule_SetScript(t *testing.T) {
|
||||
t.Run("Set non-empty script", func(t *testing.T) {
|
||||
customization := &configv1alpha1.ResourceInterpreterCustomization{
|
||||
Spec: configv1alpha1.ResourceInterpreterCustomizationSpec{
|
||||
Customizations: configv1alpha1.CustomizationRules{
|
||||
Retention: &configv1alpha1.LocalValueRetention{},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
rule := &retentionRule{}
|
||||
script := "function Retain(desiredObj, observedObj)\n desiredObj.spec.fieldFoo = observedObj.spec.fieldFoo\n return desiredObj\nend"
|
||||
|
||||
rule.SetScript(customization, script)
|
||||
if customization.Spec.Customizations.Retention.LuaScript != script {
|
||||
t.Errorf("Expected script to be set to %q, but got %q", script, customization.Spec.Customizations.Retention.LuaScript)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Set empty script", func(t *testing.T) {
|
||||
customization := &configv1alpha1.ResourceInterpreterCustomization{
|
||||
Spec: configv1alpha1.ResourceInterpreterCustomizationSpec{
|
||||
Customizations: configv1alpha1.CustomizationRules{
|
||||
Retention: nil,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
rule := &retentionRule{}
|
||||
script := ""
|
||||
|
||||
rule.SetScript(customization, script)
|
||||
if customization.Spec.Customizations.Retention != nil {
|
||||
t.Errorf("Expected retention to be nil, but got %v", customization.Spec.Customizations.Retention)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Set empty Retention", func(t *testing.T) {
|
||||
customization := &configv1alpha1.ResourceInterpreterCustomization{
|
||||
Spec: configv1alpha1.ResourceInterpreterCustomizationSpec{
|
||||
Customizations: configv1alpha1.CustomizationRules{
|
||||
Retention: nil,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
rule := &retentionRule{}
|
||||
script := "function Retain(desiredObj, observedObj)\n desiredObj.spec.fieldFoo = observedObj.spec.fieldFoo\n return desiredObj\nend"
|
||||
|
||||
rule.SetScript(customization, script)
|
||||
if customization.Spec.Customizations.Retention.LuaScript != script {
|
||||
t.Errorf("Expected script to be set to %q, but got %q", script, customization.Spec.Customizations.Retention.LuaScript)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestReplicaResourceRule_Name(t *testing.T) {
|
||||
r := &replicaResourceRule{}
|
||||
expected := string(configv1alpha1.InterpreterOperationInterpretReplica)
|
||||
actual := r.Name()
|
||||
assert.Equal(t, expected, actual, "Name should return %v", expected)
|
||||
}
|
||||
|
||||
func TestReplicaResourceRule_Document(t *testing.T) {
|
||||
rule := &replicaResourceRule{}
|
||||
expected := `This rule is used to discover the resource's replica as well as resource requirements.
|
||||
The script should implement a function as follows:
|
||||
function GetReplicas(desiredObj)
|
||||
replica = desiredObj.spec.replicas
|
||||
nodeClaim = {}
|
||||
nodeClaim.hardNodeAffinity = {}
|
||||
nodeClaim.nodeSelector = {}
|
||||
nodeClaim.tolerations = {}
|
||||
return replica, nodeClaim
|
||||
end`
|
||||
assert.Equal(t, expected, rule.Document())
|
||||
}
|
||||
|
||||
func TestReplicaResourceRule_GetScript(t *testing.T) {
|
||||
t.Run("WithScript", func(t *testing.T) {
|
||||
c := &configv1alpha1.ResourceInterpreterCustomization{
|
||||
Spec: configv1alpha1.ResourceInterpreterCustomizationSpec{
|
||||
Customizations: configv1alpha1.CustomizationRules{
|
||||
ReplicaResource: &configv1alpha1.ReplicaResourceRequirement{
|
||||
LuaScript: "return 'test script'",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
r := &replicaResourceRule{}
|
||||
script := r.GetScript(c)
|
||||
expectedScript := c.Spec.Customizations.ReplicaResource.LuaScript
|
||||
if script != expectedScript {
|
||||
t.Errorf("GetScript() returned %q, expected %q", script, expectedScript)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("WithoutScript", func(t *testing.T) {
|
||||
c := &configv1alpha1.ResourceInterpreterCustomization{
|
||||
Spec: configv1alpha1.ResourceInterpreterCustomizationSpec{
|
||||
Customizations: configv1alpha1.CustomizationRules{
|
||||
ReplicaResource: nil,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
rule := &replicaResourceRule{}
|
||||
script := rule.GetScript(c)
|
||||
|
||||
if script != "" {
|
||||
t.Errorf("GetScript() returned %q, expected an empty string", script)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestReplicaResourceRule_SetScript(t *testing.T) {
|
||||
c := &configv1alpha1.ResourceInterpreterCustomization{
|
||||
Spec: configv1alpha1.ResourceInterpreterCustomizationSpec{
|
||||
Customizations: configv1alpha1.CustomizationRules{
|
||||
ReplicaResource: &configv1alpha1.ReplicaResourceRequirement{},
|
||||
},
|
||||
},
|
||||
}
|
||||
r := &replicaResourceRule{}
|
||||
|
||||
t.Run("Empty Script", func(t *testing.T) {
|
||||
r.SetScript(c, "")
|
||||
if c.Spec.Customizations.ReplicaResource != nil {
|
||||
t.Errorf("Expected ReplicaResource to be nil, but got %v", c.Spec.Customizations.ReplicaResource)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Non-Empty Script", func(t *testing.T) {
|
||||
c.Spec.Customizations.ReplicaResource = nil
|
||||
script := "test script"
|
||||
r.SetScript(c, script)
|
||||
if c.Spec.Customizations.ReplicaResource == nil {
|
||||
t.Errorf("Expected ReplicaResource to be non-nil, but got nil")
|
||||
}
|
||||
if c.Spec.Customizations.ReplicaResource.LuaScript != "test script" {
|
||||
t.Errorf("Expected ReplicaResource.LuaScript to be %s, but got %s", script, c.Spec.Customizations.ReplicaResource.LuaScript)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestReplicaRevisionRule_Name(t *testing.T) {
|
||||
r := &replicaRevisionRule{}
|
||||
expected := string(configv1alpha1.InterpreterOperationReviseReplica)
|
||||
actual := r.Name()
|
||||
assert.Equal(t, expected, actual, "Name should return %v", expected)
|
||||
}
|
||||
|
||||
func TestReplicaRevisionRule_Document(t *testing.T) {
|
||||
rule := &replicaRevisionRule{}
|
||||
expected := `This rule is used to revise replicas in the desired specification.
|
||||
The script should implement a function as follows:
|
||||
function ReviseReplica(desiredObj, desiredReplica)
|
||||
desiredObj.spec.replicas = desiredReplica
|
||||
return desiredObj
|
||||
end`
|
||||
assert.Equal(t, expected, rule.Document())
|
||||
}
|
||||
|
||||
func TestReplicaRevisionRule_GetScript(t *testing.T) {
|
||||
t.Run("WithScript", func(t *testing.T) {
|
||||
c := &configv1alpha1.ResourceInterpreterCustomization{
|
||||
Spec: configv1alpha1.ResourceInterpreterCustomizationSpec{
|
||||
Customizations: configv1alpha1.CustomizationRules{
|
||||
ReplicaRevision: &configv1alpha1.ReplicaRevision{
|
||||
LuaScript: "return 'test script'",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
r := &replicaRevisionRule{}
|
||||
script := r.GetScript(c)
|
||||
expectedScript := c.Spec.Customizations.ReplicaRevision.LuaScript
|
||||
if script != expectedScript {
|
||||
t.Errorf("GetScript() returned %q, expected %q", script, expectedScript)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("WithoutScript", func(t *testing.T) {
|
||||
c := &configv1alpha1.ResourceInterpreterCustomization{
|
||||
Spec: configv1alpha1.ResourceInterpreterCustomizationSpec{
|
||||
Customizations: configv1alpha1.CustomizationRules{
|
||||
ReplicaRevision: nil,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
rule := &replicaRevisionRule{}
|
||||
script := rule.GetScript(c)
|
||||
|
||||
if script != "" {
|
||||
t.Errorf("GetScript() returned %q, expected an empty string", script)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestReplicaRevisionRule_SetScript(t *testing.T) {
|
||||
c := &configv1alpha1.ResourceInterpreterCustomization{
|
||||
Spec: configv1alpha1.ResourceInterpreterCustomizationSpec{
|
||||
Customizations: configv1alpha1.CustomizationRules{
|
||||
ReplicaRevision: &configv1alpha1.ReplicaRevision{},
|
||||
},
|
||||
},
|
||||
}
|
||||
r := &replicaRevisionRule{}
|
||||
|
||||
t.Run("Empty Script", func(t *testing.T) {
|
||||
r.SetScript(c, "")
|
||||
if c.Spec.Customizations.ReplicaRevision != nil {
|
||||
t.Errorf("Expected ReplicaRevision to be nil, but got %v", c.Spec.Customizations.ReplicaRevision)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Non-Empty Script", func(t *testing.T) {
|
||||
c.Spec.Customizations.ReplicaRevision = nil
|
||||
script := "test script"
|
||||
r.SetScript(c, script)
|
||||
if c.Spec.Customizations.ReplicaRevision == nil {
|
||||
t.Errorf("Expected ReplicaRevision to be non-nil, but got nil")
|
||||
}
|
||||
if c.Spec.Customizations.ReplicaRevision.LuaScript != "test script" {
|
||||
t.Errorf("Expected ReplicaRevision.LuaScript to be %s, but got %s", script, c.Spec.Customizations.ReplicaRevision.LuaScript)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestStatusReflectionRule_Name(t *testing.T) {
|
||||
r := &statusReflectionRule{}
|
||||
expected := string(configv1alpha1.InterpreterOperationInterpretStatus)
|
||||
actual := r.Name()
|
||||
assert.Equal(t, expected, actual, "Name should return %v", expected)
|
||||
}
|
||||
|
||||
func TestStatusReflectionRule_Document(t *testing.T) {
|
||||
rule := &statusReflectionRule{}
|
||||
expected := `This rule is used to get the status from the observed specification.
|
||||
The script should implement a function as follows:
|
||||
function ReflectStatus(observedObj)
|
||||
status = {}
|
||||
status.readyReplicas = observedObj.status.observedObj
|
||||
return status
|
||||
end`
|
||||
assert.Equal(t, expected, rule.Document())
|
||||
}
|
||||
|
||||
func TestStatusReflectionRule_GetScript(t *testing.T) {
|
||||
t.Run("WithScript", func(t *testing.T) {
|
||||
c := &configv1alpha1.ResourceInterpreterCustomization{
|
||||
Spec: configv1alpha1.ResourceInterpreterCustomizationSpec{
|
||||
Customizations: configv1alpha1.CustomizationRules{
|
||||
StatusReflection: &configv1alpha1.StatusReflection{
|
||||
LuaScript: "return 'test script'",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
r := &statusReflectionRule{}
|
||||
script := r.GetScript(c)
|
||||
expectedScript := c.Spec.Customizations.StatusReflection.LuaScript
|
||||
if script != expectedScript {
|
||||
t.Errorf("GetScript() returned %q, expected %q", script, expectedScript)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("WithoutScript", func(t *testing.T) {
|
||||
c := &configv1alpha1.ResourceInterpreterCustomization{
|
||||
Spec: configv1alpha1.ResourceInterpreterCustomizationSpec{
|
||||
Customizations: configv1alpha1.CustomizationRules{
|
||||
StatusReflection: nil,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
rule := &statusReflectionRule{}
|
||||
script := rule.GetScript(c)
|
||||
|
||||
if script != "" {
|
||||
t.Errorf("GetScript() returned %q, expected an empty string", script)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestStatusReflectionRule_SetScript(t *testing.T) {
|
||||
c := &configv1alpha1.ResourceInterpreterCustomization{
|
||||
Spec: configv1alpha1.ResourceInterpreterCustomizationSpec{
|
||||
Customizations: configv1alpha1.CustomizationRules{
|
||||
StatusReflection: &configv1alpha1.StatusReflection{},
|
||||
},
|
||||
},
|
||||
}
|
||||
r := &statusReflectionRule{}
|
||||
|
||||
t.Run("Empty Script", func(t *testing.T) {
|
||||
r.SetScript(c, "")
|
||||
if c.Spec.Customizations.StatusReflection != nil {
|
||||
t.Errorf("Expected StatusReflection to be nil, but got %v", c.Spec.Customizations.StatusReflection)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Non-Empty Script", func(t *testing.T) {
|
||||
c.Spec.Customizations.StatusReflection = nil
|
||||
script := "test script"
|
||||
r.SetScript(c, script)
|
||||
if c.Spec.Customizations.StatusReflection == nil {
|
||||
t.Errorf("Expected StatusReflection to be non-nil, but got nil")
|
||||
}
|
||||
if c.Spec.Customizations.StatusReflection.LuaScript != "test script" {
|
||||
t.Errorf("Expected StatusReflection.LuaScript to be %s, but got %s", script, c.Spec.Customizations.StatusReflection.LuaScript)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestStatusAggregationRule_Name(t *testing.T) {
|
||||
r := &statusAggregationRule{}
|
||||
expected := string(configv1alpha1.InterpreterOperationAggregateStatus)
|
||||
actual := r.Name()
|
||||
assert.Equal(t, expected, actual, "Name should return %v", expected)
|
||||
}
|
||||
|
||||
func TestStatusAggregationRule_Document(t *testing.T) {
|
||||
rule := &statusAggregationRule{}
|
||||
expected := `This rule is used to aggregate decentralized statuses to the desired specification.
|
||||
The script should implement a function as follows:
|
||||
function AggregateStatus(desiredObj, statusItems)
|
||||
for i = 1, #items do
|
||||
desiredObj.status.readyReplicas = desiredObj.status.readyReplicas + items[i].readyReplicas
|
||||
end
|
||||
return desiredObj
|
||||
end`
|
||||
assert.Equal(t, expected, rule.Document())
|
||||
}
|
||||
|
||||
func TestStatusAggregationRule_GetScript(t *testing.T) {
|
||||
t.Run("WithScript", func(t *testing.T) {
|
||||
c := &configv1alpha1.ResourceInterpreterCustomization{
|
||||
Spec: configv1alpha1.ResourceInterpreterCustomizationSpec{
|
||||
Customizations: configv1alpha1.CustomizationRules{
|
||||
StatusAggregation: &configv1alpha1.StatusAggregation{
|
||||
LuaScript: "return 'test script'",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
r := &statusAggregationRule{}
|
||||
script := r.GetScript(c)
|
||||
expectedScript := c.Spec.Customizations.StatusAggregation.LuaScript
|
||||
if script != expectedScript {
|
||||
t.Errorf("GetScript() returned %q, expected %q", script, expectedScript)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("WithoutScript", func(t *testing.T) {
|
||||
c := &configv1alpha1.ResourceInterpreterCustomization{
|
||||
Spec: configv1alpha1.ResourceInterpreterCustomizationSpec{
|
||||
Customizations: configv1alpha1.CustomizationRules{
|
||||
StatusAggregation: nil,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
rule := &statusAggregationRule{}
|
||||
script := rule.GetScript(c)
|
||||
|
||||
if script != "" {
|
||||
t.Errorf("GetScript() returned %q, expected an empty string", script)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestStatusAggregationRule_SetScript(t *testing.T) {
|
||||
c := &configv1alpha1.ResourceInterpreterCustomization{
|
||||
Spec: configv1alpha1.ResourceInterpreterCustomizationSpec{
|
||||
Customizations: configv1alpha1.CustomizationRules{
|
||||
StatusAggregation: &configv1alpha1.StatusAggregation{},
|
||||
},
|
||||
},
|
||||
}
|
||||
r := &statusAggregationRule{}
|
||||
|
||||
t.Run("Empty Script", func(t *testing.T) {
|
||||
r.SetScript(c, "")
|
||||
if c.Spec.Customizations.StatusAggregation != nil {
|
||||
t.Errorf("Expected StatusAggregation to be nil, but got %v", c.Spec.Customizations.StatusAggregation)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Non-Empty Script", func(t *testing.T) {
|
||||
c.Spec.Customizations.StatusAggregation = nil
|
||||
script := "test script"
|
||||
r.SetScript(c, script)
|
||||
if c.Spec.Customizations.StatusAggregation == nil {
|
||||
t.Errorf("Expected Customizations to be non-nil, but got nil")
|
||||
}
|
||||
if c.Spec.Customizations.StatusAggregation.LuaScript != "test script" {
|
||||
t.Errorf("Expected StatusAggregation.LuaScript to be %s, but got %s", script, c.Spec.Customizations.StatusAggregation.LuaScript)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestHealthInterpretationRule_Name(t *testing.T) {
|
||||
r := &healthInterpretationRule{}
|
||||
expected := string(configv1alpha1.InterpreterOperationInterpretHealth)
|
||||
actual := r.Name()
|
||||
assert.Equal(t, expected, actual, "Name should return %v", expected)
|
||||
}
|
||||
|
||||
func TestHealthInterpretationRule_Document(t *testing.T) {
|
||||
rule := &healthInterpretationRule{}
|
||||
expected := `This rule is used to assess the health state of a specific resource.
|
||||
The script should implement a function as follows:
|
||||
luaScript: >
|
||||
function InterpretHealth(observedObj)
|
||||
if observedObj.status.readyReplicas == observedObj.spec.replicas then
|
||||
return true
|
||||
end
|
||||
end`
|
||||
assert.Equal(t, expected, rule.Document())
|
||||
}
|
||||
|
||||
func TestHealthInterpretationRule_GetScript(t *testing.T) {
|
||||
t.Run("WithScript", func(t *testing.T) {
|
||||
c := &configv1alpha1.ResourceInterpreterCustomization{
|
||||
Spec: configv1alpha1.ResourceInterpreterCustomizationSpec{
|
||||
Customizations: configv1alpha1.CustomizationRules{
|
||||
HealthInterpretation: &configv1alpha1.HealthInterpretation{
|
||||
LuaScript: "return 'test script'",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
r := &healthInterpretationRule{}
|
||||
script := r.GetScript(c)
|
||||
expectedScript := c.Spec.Customizations.HealthInterpretation.LuaScript
|
||||
if script != expectedScript {
|
||||
t.Errorf("GetScript() returned %q, expected %q", script, expectedScript)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("WithoutScript", func(t *testing.T) {
|
||||
c := &configv1alpha1.ResourceInterpreterCustomization{
|
||||
Spec: configv1alpha1.ResourceInterpreterCustomizationSpec{
|
||||
Customizations: configv1alpha1.CustomizationRules{
|
||||
HealthInterpretation: nil,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
rule := &healthInterpretationRule{}
|
||||
script := rule.GetScript(c)
|
||||
|
||||
if script != "" {
|
||||
t.Errorf("GetScript() returned %q, expected an empty string", script)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestHealthInterpretationRule_SetScript(t *testing.T) {
|
||||
c := &configv1alpha1.ResourceInterpreterCustomization{
|
||||
Spec: configv1alpha1.ResourceInterpreterCustomizationSpec{
|
||||
Customizations: configv1alpha1.CustomizationRules{
|
||||
HealthInterpretation: &configv1alpha1.HealthInterpretation{},
|
||||
},
|
||||
},
|
||||
}
|
||||
r := &healthInterpretationRule{}
|
||||
|
||||
t.Run("Empty Script", func(t *testing.T) {
|
||||
r.SetScript(c, "")
|
||||
if c.Spec.Customizations.HealthInterpretation != nil {
|
||||
t.Errorf("Expected HealthInterpretation to be nil, but got %v", c.Spec.Customizations.HealthInterpretation)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Non-Empty Script", func(t *testing.T) {
|
||||
c.Spec.Customizations.HealthInterpretation = nil
|
||||
script := "test script"
|
||||
r.SetScript(c, script)
|
||||
if c.Spec.Customizations.HealthInterpretation == nil {
|
||||
t.Errorf("Expected HealthInterpretation to be non-nil, but got nil")
|
||||
}
|
||||
if c.Spec.Customizations.HealthInterpretation.LuaScript != "test script" {
|
||||
t.Errorf("Expected HealthInterpretation.LuaScript to be %s, but got %s", script, c.Spec.Customizations.HealthInterpretation.LuaScript)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestDependencyInterpretationRule_Name(t *testing.T) {
|
||||
r := &dependencyInterpretationRule{}
|
||||
expected := string(configv1alpha1.InterpreterOperationInterpretDependency)
|
||||
actual := r.Name()
|
||||
assert.Equal(t, expected, actual, "Name should return %v", expected)
|
||||
}
|
||||
|
||||
func TestDependencyInterpretationRule_Document(t *testing.T) {
|
||||
rule := &dependencyInterpretationRule{}
|
||||
expected := ` This rule is used to interpret the dependencies of a specific resource.
|
||||
The script should implement a function as follows:
|
||||
function GetDependencies(desiredObj)
|
||||
dependencies = {}
|
||||
if desiredObj.spec.serviceAccountName ~= "" and desiredObj.spec.serviceAccountName ~= "default" then
|
||||
dependency = {}
|
||||
dependency.apiVersion = "v1"
|
||||
dependency.kind = "ServiceAccount"
|
||||
dependency.name = desiredObj.spec.serviceAccountName
|
||||
dependency.namespace = desiredObj.namespace
|
||||
dependencies[0] = {}
|
||||
dependencies[0] = dependency
|
||||
end
|
||||
return dependencies
|
||||
end`
|
||||
assert.Equal(t, expected, rule.Document())
|
||||
}
|
||||
|
||||
func TestDependencyInterpretationRule_GetScript(t *testing.T) {
|
||||
t.Run("WithScript", func(t *testing.T) {
|
||||
c := &configv1alpha1.ResourceInterpreterCustomization{
|
||||
Spec: configv1alpha1.ResourceInterpreterCustomizationSpec{
|
||||
Customizations: configv1alpha1.CustomizationRules{
|
||||
DependencyInterpretation: &configv1alpha1.DependencyInterpretation{
|
||||
LuaScript: "return 'test script'",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
r := &dependencyInterpretationRule{}
|
||||
script := r.GetScript(c)
|
||||
expectedScript := c.Spec.Customizations.DependencyInterpretation.LuaScript
|
||||
if script != expectedScript {
|
||||
t.Errorf("GetScript() returned %q, expected %q", script, expectedScript)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("WithoutScript", func(t *testing.T) {
|
||||
c := &configv1alpha1.ResourceInterpreterCustomization{
|
||||
Spec: configv1alpha1.ResourceInterpreterCustomizationSpec{
|
||||
Customizations: configv1alpha1.CustomizationRules{
|
||||
DependencyInterpretation: nil,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
rule := &dependencyInterpretationRule{}
|
||||
script := rule.GetScript(c)
|
||||
|
||||
if script != "" {
|
||||
t.Errorf("GetScript() returned %q, expected an empty string", script)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestDependencyInterpretationRule_SetScript(t *testing.T) {
|
||||
c := &configv1alpha1.ResourceInterpreterCustomization{
|
||||
Spec: configv1alpha1.ResourceInterpreterCustomizationSpec{
|
||||
Customizations: configv1alpha1.CustomizationRules{
|
||||
DependencyInterpretation: &configv1alpha1.DependencyInterpretation{},
|
||||
},
|
||||
},
|
||||
}
|
||||
r := &dependencyInterpretationRule{}
|
||||
|
||||
t.Run("Empty Script", func(t *testing.T) {
|
||||
r.SetScript(c, "")
|
||||
if c.Spec.Customizations.DependencyInterpretation != nil {
|
||||
t.Errorf("Expected DependencyInterpretation to be nil, but got %v", c.Spec.Customizations.DependencyInterpretation)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Non-Empty Script", func(t *testing.T) {
|
||||
c.Spec.Customizations.DependencyInterpretation = nil
|
||||
script := "test script"
|
||||
r.SetScript(c, script)
|
||||
if c.Spec.Customizations.DependencyInterpretation == nil {
|
||||
t.Errorf("Expected DependencyInterpretation to be non-nil, but got nil")
|
||||
}
|
||||
if c.Spec.Customizations.DependencyInterpretation.LuaScript != "test script" {
|
||||
t.Errorf("Expected DependencyInterpretation.LuaScript to be %s, but got %s", script, c.Spec.Customizations.DependencyInterpretation.LuaScript)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestRulesNames(t *testing.T) {
|
||||
rule1 := &healthInterpretationRule{}
|
||||
rule2 := &dependencyInterpretationRule{}
|
||||
rules := Rules{rule1, rule2}
|
||||
|
||||
expectedNames := []string{rule1.Name(), rule2.Name()}
|
||||
actualNames := rules.Names()
|
||||
|
||||
if !reflect.DeepEqual(actualNames, expectedNames) {
|
||||
t.Errorf("Expected names %v, but got %v", expectedNames, actualNames)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetByOperation(t *testing.T) {
|
||||
rules := Rules{&healthInterpretationRule{}, &dependencyInterpretationRule{}}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
operation string
|
||||
expectedRule Rule
|
||||
}{
|
||||
{
|
||||
name: "valid operation name",
|
||||
operation: "InterpretHealth",
|
||||
expectedRule: &healthInterpretationRule{},
|
||||
},
|
||||
{
|
||||
name: "invalid operation name",
|
||||
operation: "invalid",
|
||||
expectedRule: nil,
|
||||
},
|
||||
{
|
||||
name: "empty operation name",
|
||||
operation: "",
|
||||
expectedRule: nil,
|
||||
},
|
||||
{
|
||||
name: "case-insensitive operation namee",
|
||||
operation: "InterpretDEPendency",
|
||||
expectedRule: &dependencyInterpretationRule{},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
actualRule := rules.GetByOperation(tt.operation)
|
||||
if actualRule != tt.expectedRule {
|
||||
t.Errorf("Expected rule %v, but got %v", tt.expectedRule, actualRule)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRules_Get(t *testing.T) {
|
||||
rule1 := &healthInterpretationRule{}
|
||||
rule2 := &dependencyInterpretationRule{}
|
||||
rules := Rules{rule1, rule2}
|
||||
|
||||
// Test getting a rule that exists
|
||||
result := rules.Get("InterpretHealth")
|
||||
if result != rule1 {
|
||||
t.Errorf("Expected rule1, but got %v", result)
|
||||
}
|
||||
|
||||
// Test getting a rule that does not exist
|
||||
result = rules.Get("NonexistentRule")
|
||||
if result != nil {
|
||||
t.Errorf("Expected nil, but got %v", result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetDesiredObjectOrError(t *testing.T) {
|
||||
args := RuleArgs{
|
||||
Desired: nil,
|
||||
}
|
||||
_, err := args.getDesiredObjectOrError()
|
||||
expectedErr := "desired, desired-file options are not set"
|
||||
if err == nil || err.Error() != expectedErr {
|
||||
t.Errorf("getDesiredObjectOrError() returned unexpected error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetObservedObjectOrError(t *testing.T) {
|
||||
args := RuleArgs{}
|
||||
_, err := args.getObservedObjectOrError()
|
||||
if err == nil {
|
||||
t.Errorf("Expected error, but got nil")
|
||||
}
|
||||
|
||||
obj := &unstructured.Unstructured{}
|
||||
args.Observed = obj
|
||||
result, err := args.getObservedObjectOrError()
|
||||
if err != nil {
|
||||
t.Errorf("Expected nil error, but got %v", err)
|
||||
}
|
||||
if result != obj {
|
||||
t.Errorf("Expected %v, but got %v", obj, result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetObjectOrError(t *testing.T) {
|
||||
desired := &unstructured.Unstructured{}
|
||||
observed := &unstructured.Unstructured{}
|
||||
|
||||
t.Run("Both desired and observed objects are nil", func(t *testing.T) {
|
||||
args := RuleArgs{}
|
||||
_, err := args.getObjectOrError()
|
||||
if err == nil {
|
||||
t.Errorf("Expected error, but got nil")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Both desired and observed objects are set", func(t *testing.T) {
|
||||
args := RuleArgs{Desired: desired, Observed: observed}
|
||||
_, err := args.getObjectOrError()
|
||||
if err == nil {
|
||||
t.Errorf("Expected error, but got nil")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Only desired object is set", func(t *testing.T) {
|
||||
args := RuleArgs{Desired: desired}
|
||||
obj, err := args.getObjectOrError()
|
||||
if err != nil {
|
||||
t.Errorf("Expected nil error, but got %v", err)
|
||||
}
|
||||
if obj != desired {
|
||||
t.Errorf("Expected %v, but got %v", desired, obj)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Only observed object is set", func(t *testing.T) {
|
||||
args := RuleArgs{Observed: observed}
|
||||
obj, err := args.getObjectOrError()
|
||||
if err != nil {
|
||||
t.Errorf("Expected nil error, but got %v", err)
|
||||
}
|
||||
if obj != observed {
|
||||
t.Errorf("Expected %v, but got %v", observed, obj)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestNewRuleResult(t *testing.T) {
|
||||
result := newRuleResult()
|
||||
if result.Err != nil {
|
||||
t.Errorf("Expected error to be nil, but got %v", result.Err)
|
||||
}
|
||||
if len(result.Results) != 0 {
|
||||
t.Errorf("Expected results to be empty, but got %v", result.Results)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewRuleResultWithError(t *testing.T) {
|
||||
err := fmt.Errorf("test error")
|
||||
result := newRuleResultWithError(err)
|
||||
if result.Err != err {
|
||||
t.Errorf("expected error %v, but got %v", err, result.Err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRuleResultAdd(t *testing.T) {
|
||||
r := newRuleResult()
|
||||
r.add("test1", "value1")
|
||||
r.add("test2", 2)
|
||||
if len(r.Results) != 2 {
|
||||
t.Errorf("Expected 2 results, but got %d", len(r.Results))
|
||||
}
|
||||
if r.Results[0].Name != "test1" || r.Results[0].Value != "value1" {
|
||||
t.Errorf("Unexpected result at index 0: %v", r.Results[0])
|
||||
}
|
||||
if r.Results[1].Name != "test2" || r.Results[1].Value != 2 {
|
||||
t.Errorf("Unexpected result at index 1: %v", r.Results[1])
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue