github.com/oam-dev/kubevela@v1.9.11/pkg/resourcekeeper/cache_test.go (about) 1 /* 2 Copyright 2021 The KubeVela Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package resourcekeeper 18 19 import ( 20 "context" 21 "testing" 22 23 "github.com/stretchr/testify/require" 24 appsv1 "k8s.io/api/apps/v1" 25 corev1 "k8s.io/api/core/v1" 26 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 27 "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" 28 "sigs.k8s.io/controller-runtime/pkg/client/fake" 29 30 apicommon "github.com/oam-dev/kubevela/apis/core.oam.dev/common" 31 "github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1" 32 "github.com/oam-dev/kubevela/pkg/oam" 33 "github.com/oam-dev/kubevela/pkg/utils/common" 34 ) 35 36 func TestResourceCache(t *testing.T) { 37 cli := fake.NewClientBuilder().WithScheme(common.Scheme).Build() 38 cache := newResourceCache(cli, nil) 39 r := require.New(t) 40 createMR := func(name string) v1beta1.ManagedResource { 41 return v1beta1.ManagedResource{ 42 ClusterObjectReference: apicommon.ClusterObjectReference{ 43 ObjectReference: corev1.ObjectReference{ 44 Name: name, 45 Kind: "Deployment", 46 APIVersion: appsv1.SchemeGroupVersion.String(), 47 }, 48 }, 49 } 50 } 51 r.NoError(cli.Create(context.Background(), &appsv1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: "resource-1"}})) 52 r.NoError(cli.Create(context.Background(), &appsv1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: "resource-2"}})) 53 r.NoError(cli.Create(context.Background(), &appsv1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: "resource-3"}})) 54 r.NoError(cli.Create(context.Background(), &appsv1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: "resource-4"}})) 55 r.NoError(cli.Create(context.Background(), &appsv1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: "resource-6"}})) 56 ti := metav1.Now() 57 rt1 := &v1beta1.ResourceTracker{ 58 Spec: v1beta1.ResourceTrackerSpec{ 59 ManagedResources: []v1beta1.ManagedResource{ 60 createMR("resource-1"), 61 createMR("resource-3"), 62 }, 63 }, 64 } 65 rt2 := &v1beta1.ResourceTracker{ 66 ObjectMeta: metav1.ObjectMeta{DeletionTimestamp: &ti}, 67 Spec: v1beta1.ResourceTrackerSpec{ 68 ManagedResources: []v1beta1.ManagedResource{ 69 createMR("resource-1"), 70 createMR("resource-2"), 71 createMR("resource-3"), 72 createMR("resource-4"), 73 }, 74 }, 75 } 76 rt3 := &v1beta1.ResourceTracker{ 77 Spec: v1beta1.ResourceTrackerSpec{ 78 ManagedResources: []v1beta1.ManagedResource{ 79 createMR("resource-1"), 80 createMR("resource-4"), 81 createMR("resource-5"), 82 }, 83 }, 84 } 85 rts := []*v1beta1.ResourceTracker{nil, rt1, rt2, rt3} 86 cache.registerResourceTrackers(rts...) 87 mr := createMR("resource-1") 88 o, ok := cache.m.Get(mr.ResourceKey()) 89 r.True(ok) 90 r.False(o.loaded) 91 for _, check := range []struct { 92 name string 93 usedBy []*v1beta1.ResourceTracker 94 latestActiveRT *v1beta1.ResourceTracker 95 gcExecutorRT *v1beta1.ResourceTracker 96 notFound bool 97 }{{ 98 name: "resource-1", 99 usedBy: []*v1beta1.ResourceTracker{rt1, rt2, rt3}, 100 latestActiveRT: rt3, 101 gcExecutorRT: rt3, 102 }, { 103 name: "resource-2", 104 usedBy: []*v1beta1.ResourceTracker{rt2}, 105 latestActiveRT: nil, 106 gcExecutorRT: rt2, 107 }, { 108 name: "resource-3", 109 usedBy: []*v1beta1.ResourceTracker{rt1, rt2}, 110 latestActiveRT: rt1, 111 gcExecutorRT: rt1, 112 }, { 113 name: "resource-4", 114 usedBy: []*v1beta1.ResourceTracker{rt2, rt3}, 115 latestActiveRT: rt3, 116 gcExecutorRT: rt3, 117 }, { 118 name: "resource-5", 119 usedBy: []*v1beta1.ResourceTracker{rt3}, 120 latestActiveRT: rt3, 121 gcExecutorRT: rt3, 122 notFound: true, 123 }, { 124 name: "resource-6", 125 }} { 126 entry := cache.get(context.Background(), createMR(check.name)) 127 r.Equal(check.usedBy, entry.usedBy) 128 r.Equal(check.latestActiveRT, entry.latestActiveRT) 129 r.Equal(check.gcExecutorRT, entry.gcExecutorRT) 130 r.Equal(check.notFound, !entry.exists) 131 r.True(entry.loaded) 132 } 133 } 134 135 func TestResourceCacheExistenceCheck(t *testing.T) { 136 cli := fake.NewClientBuilder().WithScheme(common.Scheme).Build() 137 cache := newResourceCache(cli, &v1beta1.Application{ObjectMeta: metav1.ObjectMeta{ 138 Name: "app", 139 Namespace: "test", 140 }}) 141 r := require.New(t) 142 createResource := func(appName, appNs, sharedBy string) *unstructured.Unstructured { 143 return &unstructured.Unstructured{Object: map[string]interface{}{ 144 "metadata": map[string]interface{}{ 145 "labels": map[string]interface{}{oam.LabelAppName: appName, oam.LabelAppNamespace: appNs}, 146 "annotations": map[string]interface{}{oam.AnnotationAppSharedBy: sharedBy}, 147 "resourceVersion": "-", 148 }, 149 }} 150 } 151 r.True(cache.exists(createResource("app", "test", ""))) 152 r.False(cache.exists(createResource("app-no-shared-by", "test", ""))) 153 r.True(cache.exists(createResource("app-shared-by", "ex", "x/y,test/app,ex/app-shared-by"))) 154 }