github.com/kiali/kiali@v1.84.0/kubernetes/cache/cache_test.go (about) 1 package cache_test 2 3 import ( 4 "sync" 5 "testing" 6 7 "github.com/stretchr/testify/require" 8 apps_v1 "k8s.io/api/apps/v1" 9 core_v1 "k8s.io/api/core/v1" 10 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 11 12 "github.com/kiali/kiali/config" 13 "github.com/kiali/kiali/kubernetes" 14 "github.com/kiali/kiali/kubernetes/cache" 15 "github.com/kiali/kiali/kubernetes/kubetest" 16 "github.com/kiali/kiali/models" 17 ) 18 19 func TestNoHomeClusterReturnsError(t *testing.T) { 20 require := require.New(t) 21 conf := config.NewConfig() 22 config.Set(conf) 23 24 client := kubetest.NewFakeK8sClient() 25 clientFactory := kubetest.NewK8SClientFactoryMock(client) 26 clientFactory.SetClients(map[string]kubernetes.ClientInterface{"nothomecluster": client}) 27 28 cache, err := cache.NewKialiCache(clientFactory, *conf) 29 defer func() { 30 if cache != nil { 31 cache.Stop() 32 } 33 }() 34 require.Error(err, "no home cluster should return an error") 35 } 36 37 func TestKubeCacheCreatedPerClient(t *testing.T) { 38 require := require.New(t) 39 conf := config.NewConfig() 40 config.Set(conf) 41 42 ns := &core_v1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "test"}} 43 deploymentCluster1 := &apps_v1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: "deployment1", Namespace: "test"}} 44 deploymentCluster2 := &apps_v1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: "deployment2", Namespace: "test"}} 45 client := kubetest.NewFakeK8sClient(ns, deploymentCluster1) 46 client2 := kubetest.NewFakeK8sClient(ns, deploymentCluster2) 47 clientFactory := kubetest.NewK8SClientFactoryMock(nil) 48 clientFactory.SetClients(map[string]kubernetes.ClientInterface{ 49 conf.KubernetesConfig.ClusterName: client, 50 "cluster2": client2, 51 }) 52 53 kialiCache := cache.NewTestingCacheWithFactory(t, clientFactory, *conf) 54 55 caches := kialiCache.GetKubeCaches() 56 require.Equal(2, len(caches)) 57 58 _, err := caches[conf.KubernetesConfig.ClusterName].GetDeployment("test", "deployment1") 59 require.NoError(err) 60 61 _, err = caches["cluster2"].GetDeployment("test", "deployment2") 62 require.NoError(err) 63 64 _, err = kialiCache.GetKubeCache(conf.KubernetesConfig.ClusterName) 65 require.NoError(err) 66 67 _, err = kialiCache.GetKubeCache("cluster2") 68 require.NoError(err) 69 70 _, err = kialiCache.GetKubeCache("cluster3") 71 require.Error(err) 72 } 73 74 func ztunnelDaemonSet() *apps_v1.DaemonSet { 75 return &apps_v1.DaemonSet{ 76 ObjectMeta: metav1.ObjectMeta{ 77 Name: "ztunnel", 78 Namespace: "istio-system", 79 }, 80 Spec: apps_v1.DaemonSetSpec{ 81 Selector: &metav1.LabelSelector{ 82 MatchLabels: map[string]string{"app": "ztunnel"}, 83 }, 84 }, 85 } 86 } 87 88 func TestIsAmbientEnabled(t *testing.T) { 89 require := require.New(t) 90 conf := config.NewConfig() 91 client := kubetest.NewFakeK8sClient( 92 &core_v1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "istio-system"}}, 93 ztunnelDaemonSet(), 94 ) 95 cache := cache.NewTestingCache(t, client, *conf) 96 97 require.True(cache.IsAmbientEnabled(conf.KubernetesConfig.ClusterName)) 98 // Call multiple times to ensure results are consistent. 99 require.True(cache.IsAmbientEnabled(conf.KubernetesConfig.ClusterName)) 100 } 101 102 func TestIsAmbientEnabledOutsideIstioSystem(t *testing.T) { 103 require := require.New(t) 104 conf := config.NewConfig() 105 ztunnel := ztunnelDaemonSet() 106 ztunnel.Namespace = "alternate-istio-namespace" 107 client := kubetest.NewFakeK8sClient( 108 &core_v1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "alternate-istio-namespace"}}, 109 ztunnel, 110 ) 111 cache := cache.NewTestingCache(t, client, *conf) 112 113 require.True(cache.IsAmbientEnabled(conf.KubernetesConfig.ClusterName)) 114 // Call multiple times to ensure results are consistent. 115 require.True(cache.IsAmbientEnabled(conf.KubernetesConfig.ClusterName)) 116 } 117 118 func TestIsAmbientDisabled(t *testing.T) { 119 require := require.New(t) 120 conf := config.NewConfig() 121 client := kubetest.NewFakeK8sClient( 122 &core_v1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "istio-system"}}, 123 ) 124 cache := cache.NewTestingCache(t, client, *conf) 125 126 require.False(cache.IsAmbientEnabled(conf.KubernetesConfig.ClusterName)) 127 // Call multiple times to ensure results are consistent. 128 require.False(cache.IsAmbientEnabled(conf.KubernetesConfig.ClusterName)) 129 } 130 131 func TestIsAmbientMultiCluster(t *testing.T) { 132 require := require.New(t) 133 conf := config.NewConfig() 134 conf.KubernetesConfig.ClusterName = "east" 135 east := kubetest.NewFakeK8sClient( 136 &core_v1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "istio-system"}}, 137 ztunnelDaemonSet(), 138 ) 139 west := kubetest.NewFakeK8sClient( 140 &core_v1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "istio-system"}}, 141 ) 142 clientFactory := kubetest.NewK8SClientFactoryMock(nil) 143 clientFactory.SetClients(map[string]kubernetes.ClientInterface{ 144 "east": east, 145 "west": west, 146 }) 147 cache := cache.NewTestingCacheWithFactory(t, clientFactory, *conf) 148 149 require.True(cache.IsAmbientEnabled("east")) 150 require.False(cache.IsAmbientEnabled("west")) 151 } 152 153 // This test only tests anything when the '-race' flag is passed to 'go test'. 154 func TestIsAmbientIsThreadSafe(t *testing.T) { 155 conf := config.NewConfig() 156 client := kubetest.NewFakeK8sClient( 157 &core_v1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "istio-system"}}, 158 ztunnelDaemonSet(), 159 ) 160 cache := cache.NewTestingCache(t, client, *conf) 161 162 wg := sync.WaitGroup{} 163 for i := 0; i < 10; i++ { 164 wg.Add(1) 165 go func() { 166 defer wg.Done() 167 cache.IsAmbientEnabled(conf.KubernetesConfig.ClusterName) 168 }() 169 } 170 wg.Wait() 171 } 172 173 func TestSetNamespace(t *testing.T) { 174 require := require.New(t) 175 176 conf := config.NewConfig() 177 conf.KubernetesConfig.CacheTokenNamespaceDuration = 10000 178 conf.KubernetesConfig.ClusterName = "east" 179 kubernetes.SetConfig(t, *conf) 180 181 client := kubetest.NewFakeK8sClient() 182 cache := cache.NewTestingCache(t, client, *conf) 183 cache.SetNamespaces("token", []models.Namespace{{Name: "test", Cluster: "east"}}) 184 cache.SetNamespace("token", models.Namespace{Name: "test", Cluster: "east", Labels: map[string]string{"app": "test"}}) 185 186 ns, found := cache.GetNamespace("east", "token", "test") 187 require.True(found) 188 require.Equal(map[string]string{"app": "test"}, ns.Labels) 189 } 190 191 func TestSetNamespaceIsThreadSafe(t *testing.T) { 192 conf := config.NewConfig() 193 conf.KubernetesConfig.CacheTokenNamespaceDuration = 10000 194 conf.KubernetesConfig.ClusterName = "east" 195 kubernetes.SetConfig(t, *conf) 196 197 client := kubetest.NewFakeK8sClient() 198 cache := cache.NewTestingCache(t, client, *conf) 199 200 wg := sync.WaitGroup{} 201 for i := 0; i < 10; i++ { 202 wg.Add(1) 203 go func() { 204 defer wg.Done() 205 cache.SetNamespace("token", models.Namespace{Name: "test", Cluster: "east", Labels: map[string]string{"app": "test"}}) 206 }() 207 } 208 wg.Wait() 209 } 210 211 func TestGetNamespaces(t *testing.T) { 212 require := require.New(t) 213 conf := config.NewConfig() 214 conf.KubernetesConfig.CacheTokenNamespaceDuration = 10000 215 conf.KubernetesConfig.ClusterName = "east" 216 kubernetes.SetConfig(t, *conf) 217 218 client := kubetest.NewFakeK8sClient() 219 cache := cache.NewTestingCache(t, client, *conf) 220 cache.SetNamespaces("token", []models.Namespace{{Name: "test", Cluster: "east"}}) 221 222 namespaces, found := cache.GetNamespaces("east", "token") 223 require.True(found) 224 require.Equal(1, len(namespaces)) 225 require.Equal("test", namespaces[0].Name) 226 227 _, found = cache.GetNamespaces("west", "token") 228 require.False(found) 229 230 _, found = cache.GetNamespaces("east", "token2") 231 require.False(found) 232 } 233 234 func TestRefreshTokenNamespaces(t *testing.T) { 235 require := require.New(t) 236 conf := config.NewConfig() 237 conf.KubernetesConfig.CacheTokenNamespaceDuration = 10000 238 conf.KubernetesConfig.ClusterName = "east" 239 kubernetes.SetConfig(t, *conf) 240 241 client := kubetest.NewFakeK8sClient() 242 cache := cache.NewTestingCache(t, client, *conf) 243 cache.SetNamespaces("token", []models.Namespace{{Name: "test", Cluster: "east"}}) 244 cache.RefreshTokenNamespaces("east") 245 246 _, found := cache.GetNamespaces("east", "token") 247 require.False(found) 248 249 // Test refresh doesn't affect other clusters. 250 cache.SetNamespaces("token", []models.Namespace{{Name: "test", Cluster: "east"}}) 251 cache.SetNamespaces("token", []models.Namespace{{Name: "test", Cluster: "west"}}) 252 cache.RefreshTokenNamespaces("east") 253 254 namespaces, found := cache.GetNamespaces("west", "token") 255 require.True(found) 256 require.Equal(1, len(namespaces)) 257 require.Equal("test", namespaces[0].Name) 258 }