Merge pull request #5742 from anujagrawal699/addedTests-pkg/util/helper/work.go
Added tests for pkg/util/helper/work.go
This commit is contained in:
commit
492e24dd8c
|
@ -17,13 +17,360 @@ limitations under the License.
|
|||
package helper
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/utils/ptr"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client/fake"
|
||||
|
||||
workv1alpha1 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha1"
|
||||
workv1alpha2 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha2"
|
||||
"github.com/karmada-io/karmada/pkg/util"
|
||||
)
|
||||
|
||||
func TestCreateOrUpdateWork(t *testing.T) {
|
||||
scheme := runtime.NewScheme()
|
||||
assert.NoError(t, workv1alpha1.Install(scheme))
|
||||
assert.NoError(t, workv1alpha2.Install(scheme))
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
existingWork *workv1alpha1.Work
|
||||
workMeta metav1.ObjectMeta
|
||||
resource *unstructured.Unstructured
|
||||
wantErr bool
|
||||
verify func(*testing.T, client.Client)
|
||||
}{
|
||||
{
|
||||
name: "create new work",
|
||||
workMeta: metav1.ObjectMeta{
|
||||
Namespace: "default",
|
||||
Name: "test-work",
|
||||
},
|
||||
resource: &unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"apiVersion": "apps/v1",
|
||||
"kind": "Deployment",
|
||||
"metadata": map[string]interface{}{
|
||||
"name": "test-deployment",
|
||||
"uid": "test-uid",
|
||||
},
|
||||
},
|
||||
},
|
||||
verify: func(t *testing.T, c client.Client) {
|
||||
work := &workv1alpha1.Work{}
|
||||
err := c.Get(context.TODO(), client.ObjectKey{Namespace: "default", Name: "test-work"}, work)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "test-work", work.Name)
|
||||
assert.Equal(t, 1, len(work.Spec.Workload.Manifests))
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "create work with PropagationInstruction",
|
||||
workMeta: metav1.ObjectMeta{
|
||||
Namespace: "default",
|
||||
Name: "test-work",
|
||||
Labels: map[string]string{
|
||||
util.PropagationInstruction: "some-value",
|
||||
},
|
||||
Annotations: map[string]string{
|
||||
workv1alpha2.ResourceConflictResolutionAnnotation: "overwrite",
|
||||
},
|
||||
},
|
||||
resource: &unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"apiVersion": "apps/v1",
|
||||
"kind": "Deployment",
|
||||
"metadata": map[string]interface{}{
|
||||
"name": "test-deployment",
|
||||
"uid": "test-uid",
|
||||
},
|
||||
},
|
||||
},
|
||||
verify: func(t *testing.T, c client.Client) {
|
||||
work := &workv1alpha1.Work{}
|
||||
err := c.Get(context.TODO(), client.ObjectKey{Namespace: "default", Name: "test-work"}, work)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Get the resource from manifests
|
||||
manifest := &unstructured.Unstructured{}
|
||||
err = manifest.UnmarshalJSON(work.Spec.Workload.Manifests[0].Raw)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Verify labels and annotations were set
|
||||
labels := manifest.GetLabels()
|
||||
assert.Equal(t, util.ManagedByKarmadaLabelValue, labels[util.ManagedByKarmadaLabel])
|
||||
|
||||
annotations := manifest.GetAnnotations()
|
||||
assert.Equal(t, "test-uid", annotations[workv1alpha2.ResourceTemplateUIDAnnotation])
|
||||
assert.Equal(t, "test-work", annotations[workv1alpha2.WorkNameAnnotation])
|
||||
assert.Equal(t, "default", annotations[workv1alpha2.WorkNamespaceAnnotation])
|
||||
assert.Equal(t, "overwrite", annotations[workv1alpha2.ResourceConflictResolutionAnnotation])
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "create work with PropagationInstructionSuppressed",
|
||||
workMeta: metav1.ObjectMeta{
|
||||
Namespace: "default",
|
||||
Name: "test-work",
|
||||
Labels: map[string]string{
|
||||
util.PropagationInstruction: util.PropagationInstructionSuppressed,
|
||||
},
|
||||
},
|
||||
resource: &unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"apiVersion": "apps/v1",
|
||||
"kind": "Deployment",
|
||||
"metadata": map[string]interface{}{
|
||||
"name": "test-deployment",
|
||||
"uid": "test-uid",
|
||||
},
|
||||
},
|
||||
},
|
||||
verify: func(t *testing.T, c client.Client) {
|
||||
work := &workv1alpha1.Work{}
|
||||
err := c.Get(context.TODO(), client.ObjectKey{Namespace: "default", Name: "test-work"}, work)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Get the resource from manifests
|
||||
manifest := &unstructured.Unstructured{}
|
||||
err = manifest.UnmarshalJSON(work.Spec.Workload.Manifests[0].Raw)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Verify labels and annotations were NOT set
|
||||
labels := manifest.GetLabels()
|
||||
assert.Empty(t, labels[util.ManagedByKarmadaLabel])
|
||||
|
||||
annotations := manifest.GetAnnotations()
|
||||
assert.Empty(t, annotations[workv1alpha2.ResourceTemplateUIDAnnotation])
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "update existing work",
|
||||
existingWork: &workv1alpha1.Work{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: "default",
|
||||
Name: "test-work",
|
||||
},
|
||||
},
|
||||
workMeta: metav1.ObjectMeta{
|
||||
Namespace: "default",
|
||||
Name: "test-work",
|
||||
},
|
||||
resource: &unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"apiVersion": "apps/v1",
|
||||
"kind": "Deployment",
|
||||
"metadata": map[string]interface{}{
|
||||
"name": "test-deployment",
|
||||
"uid": "test-uid",
|
||||
},
|
||||
},
|
||||
},
|
||||
verify: func(t *testing.T, c client.Client) {
|
||||
work := &workv1alpha1.Work{}
|
||||
err := c.Get(context.TODO(), client.ObjectKey{Namespace: "default", Name: "test-work"}, work)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 1, len(work.Spec.Workload.Manifests))
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "error when work is being deleted",
|
||||
existingWork: &workv1alpha1.Work{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: "default",
|
||||
Name: "test-work",
|
||||
DeletionTimestamp: &metav1.Time{Time: time.Now()},
|
||||
Finalizers: []string{"test.finalizer.io"}, // Finalizer to satisfy fake client requirement
|
||||
},
|
||||
Spec: workv1alpha1.WorkSpec{
|
||||
Workload: workv1alpha1.WorkloadTemplate{
|
||||
Manifests: []workv1alpha1.Manifest{
|
||||
{
|
||||
RawExtension: runtime.RawExtension{
|
||||
Raw: []byte(`{"apiVersion":"apps/v1","kind":"Deployment","metadata":{"name":"test-deployment"}}`),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
workMeta: metav1.ObjectMeta{
|
||||
Namespace: "default",
|
||||
Name: "test-work",
|
||||
},
|
||||
resource: &unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"apiVersion": "apps/v1",
|
||||
"kind": "Deployment",
|
||||
"metadata": map[string]interface{}{
|
||||
"name": "test-deployment",
|
||||
},
|
||||
},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
c := fake.NewClientBuilder().WithScheme(scheme)
|
||||
if tt.existingWork != nil {
|
||||
c = c.WithObjects(tt.existingWork)
|
||||
}
|
||||
client := c.Build()
|
||||
|
||||
err := CreateOrUpdateWork(context.TODO(), client, tt.workMeta, tt.resource)
|
||||
|
||||
if tt.wantErr {
|
||||
assert.Error(t, err)
|
||||
return
|
||||
}
|
||||
assert.NoError(t, err)
|
||||
if tt.verify != nil {
|
||||
tt.verify(t, client)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetWorksByLabelsSet(t *testing.T) {
|
||||
scheme := runtime.NewScheme()
|
||||
assert.NoError(t, workv1alpha1.Install(scheme))
|
||||
|
||||
work1 := &workv1alpha1.Work{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "work1",
|
||||
Labels: map[string]string{
|
||||
"app": "test",
|
||||
},
|
||||
},
|
||||
}
|
||||
work2 := &workv1alpha1.Work{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "work2",
|
||||
Labels: map[string]string{
|
||||
"app": "other",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
works []client.Object
|
||||
labels labels.Set
|
||||
wantCount int
|
||||
}{
|
||||
{
|
||||
name: "no works exist",
|
||||
works: []client.Object{},
|
||||
labels: labels.Set{"app": "test"},
|
||||
wantCount: 0,
|
||||
},
|
||||
{
|
||||
name: "find work by label",
|
||||
works: []client.Object{work1, work2},
|
||||
labels: labels.Set{"app": "test"},
|
||||
wantCount: 1,
|
||||
},
|
||||
{
|
||||
name: "find multiple works",
|
||||
works: []client.Object{work1, work2},
|
||||
labels: labels.Set{},
|
||||
wantCount: 2,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
client := fake.NewClientBuilder().
|
||||
WithScheme(scheme).
|
||||
WithObjects(tt.works...).
|
||||
Build()
|
||||
|
||||
workList, err := GetWorksByLabelsSet(context.TODO(), client, tt.labels)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, tt.wantCount, len(workList.Items))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetWorksByBindingID(t *testing.T) {
|
||||
scheme := runtime.NewScheme()
|
||||
assert.NoError(t, workv1alpha1.Install(scheme))
|
||||
|
||||
bindingID := "test-binding-id"
|
||||
work1 := &workv1alpha1.Work{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "work1",
|
||||
Labels: map[string]string{
|
||||
workv1alpha2.ResourceBindingPermanentIDLabel: bindingID,
|
||||
},
|
||||
},
|
||||
}
|
||||
work2 := &workv1alpha1.Work{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "work2",
|
||||
Labels: map[string]string{
|
||||
workv1alpha2.ClusterResourceBindingPermanentIDLabel: bindingID,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
works []client.Object
|
||||
bindingID string
|
||||
namespaced bool
|
||||
wantWorks []string
|
||||
}{
|
||||
{
|
||||
name: "find namespaced binding works",
|
||||
works: []client.Object{work1, work2},
|
||||
bindingID: bindingID,
|
||||
namespaced: true,
|
||||
wantWorks: []string{"work1"},
|
||||
},
|
||||
{
|
||||
name: "find cluster binding works",
|
||||
works: []client.Object{work1, work2},
|
||||
bindingID: bindingID,
|
||||
namespaced: false,
|
||||
wantWorks: []string{"work2"},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
client := fake.NewClientBuilder().
|
||||
WithScheme(scheme).
|
||||
WithObjects(tt.works...).
|
||||
Build()
|
||||
|
||||
workList, err := GetWorksByBindingID(context.TODO(), client, tt.bindingID, tt.namespaced)
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, len(tt.wantWorks), len(workList.Items))
|
||||
|
||||
// Verify the correct works were returned
|
||||
foundWorkNames := make([]string, len(workList.Items))
|
||||
for i, work := range workList.Items {
|
||||
foundWorkNames[i] = work.Name
|
||||
}
|
||||
assert.ElementsMatch(t, tt.wantWorks, foundWorkNames)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenEventRef(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
|
@ -93,17 +440,157 @@ func TestGenEventRef(t *testing.T) {
|
|||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "empty kind",
|
||||
obj: &unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"apiVersion": "v1",
|
||||
"metadata": map[string]interface{}{
|
||||
"name": "test-obj",
|
||||
"uid": "test-uid",
|
||||
},
|
||||
},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "empty name",
|
||||
obj: &unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Pod",
|
||||
"metadata": map[string]interface{}{
|
||||
"uid": "test-uid",
|
||||
},
|
||||
},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "missing uid but has annotation",
|
||||
obj: &unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Pod",
|
||||
"metadata": map[string]interface{}{
|
||||
"name": "test-pod",
|
||||
"annotations": map[string]interface{}{
|
||||
workv1alpha2.ResourceTemplateUIDAnnotation: "annotation-uid",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
want: &corev1.ObjectReference{
|
||||
APIVersion: "v1",
|
||||
Kind: "Pod",
|
||||
Name: "test-pod",
|
||||
UID: "annotation-uid",
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
actual, err := GenEventRef(tt.obj)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("GenEventRef() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
if !reflect.DeepEqual(actual, tt.want) {
|
||||
t.Errorf("GenEventRef() = %v, want %v", actual, tt.want)
|
||||
if tt.wantErr {
|
||||
assert.Error(t, err)
|
||||
assert.Nil(t, actual)
|
||||
} else {
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, tt.want, actual)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsWorkContains(t *testing.T) {
|
||||
deployment := unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"apiVersion": "apps/v1",
|
||||
"kind": "Deployment",
|
||||
},
|
||||
}
|
||||
deploymentData, _ := deployment.MarshalJSON()
|
||||
|
||||
service := unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Service",
|
||||
},
|
||||
}
|
||||
serviceData, _ := service.MarshalJSON()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
manifests []workv1alpha1.Manifest
|
||||
targetResource schema.GroupVersionKind
|
||||
want bool
|
||||
}{
|
||||
{
|
||||
name: "resource exists in manifests",
|
||||
manifests: []workv1alpha1.Manifest{
|
||||
{RawExtension: runtime.RawExtension{Raw: deploymentData}},
|
||||
{RawExtension: runtime.RawExtension{Raw: serviceData}},
|
||||
},
|
||||
targetResource: schema.GroupVersionKind{Group: "apps", Version: "v1", Kind: "Deployment"},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "resource does not exist in manifests",
|
||||
manifests: []workv1alpha1.Manifest{
|
||||
{RawExtension: runtime.RawExtension{Raw: serviceData}},
|
||||
},
|
||||
targetResource: schema.GroupVersionKind{Group: "apps", Version: "v1", Kind: "Deployment"},
|
||||
want: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := IsWorkContains(tt.manifests, tt.targetResource)
|
||||
assert.Equal(t, tt.want, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsWorkSuspendDispatching(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
work *workv1alpha1.Work
|
||||
want bool
|
||||
}{
|
||||
{
|
||||
name: "dispatching is suspended",
|
||||
work: &workv1alpha1.Work{
|
||||
Spec: workv1alpha1.WorkSpec{
|
||||
SuspendDispatching: ptr.To(true),
|
||||
},
|
||||
},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "dispatching is not suspended",
|
||||
work: &workv1alpha1.Work{
|
||||
Spec: workv1alpha1.WorkSpec{
|
||||
SuspendDispatching: ptr.To(false),
|
||||
},
|
||||
},
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "suspend dispatching is nil",
|
||||
work: &workv1alpha1.Work{
|
||||
Spec: workv1alpha1.WorkSpec{},
|
||||
},
|
||||
want: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := IsWorkSuspendDispatching(tt.work)
|
||||
assert.Equal(t, tt.want, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue