...

Source file src/k8s.io/kubernetes/pkg/kubelet/configmap/configmap_manager_test.go

Documentation: k8s.io/kubernetes/pkg/kubelet/configmap

     1  /*
     2  Copyright 2017 The Kubernetes 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 configmap
    18  
    19  import (
    20  	"context"
    21  	"fmt"
    22  	"strings"
    23  	"testing"
    24  	"time"
    25  
    26  	"k8s.io/api/core/v1"
    27  
    28  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    29  	"k8s.io/apimachinery/pkg/runtime"
    30  
    31  	clientset "k8s.io/client-go/kubernetes"
    32  	"k8s.io/client-go/kubernetes/fake"
    33  	"k8s.io/kubernetes/pkg/kubelet/util/manager"
    34  	"k8s.io/utils/clock"
    35  )
    36  
    37  func checkObject(t *testing.T, store manager.Store, ns, name string, shouldExist bool) {
    38  	_, err := store.Get(ns, name)
    39  	if shouldExist && err != nil {
    40  		t.Errorf("unexpected actions: %#v", err)
    41  	}
    42  	if !shouldExist && (err == nil || !strings.Contains(err.Error(), fmt.Sprintf("object %q/%q not registered", ns, name))) {
    43  		t.Errorf("unexpected actions: %#v", err)
    44  	}
    45  }
    46  
    47  func noObjectTTL() (time.Duration, bool) {
    48  	return time.Duration(0), false
    49  }
    50  
    51  func getConfigMap(fakeClient clientset.Interface) manager.GetObjectFunc {
    52  	return func(namespace, name string, opts metav1.GetOptions) (runtime.Object, error) {
    53  		return fakeClient.CoreV1().ConfigMaps(namespace).Get(context.TODO(), name, opts)
    54  	}
    55  }
    56  
    57  type envConfigMaps struct {
    58  	envVarNames  []string
    59  	envFromNames []string
    60  }
    61  
    62  type configMapsToAttach struct {
    63  	containerEnvConfigMaps []envConfigMaps
    64  	volumes                []string
    65  }
    66  
    67  func podWithConfigMaps(ns, podName string, toAttach configMapsToAttach) *v1.Pod {
    68  	pod := &v1.Pod{
    69  		ObjectMeta: metav1.ObjectMeta{
    70  			Namespace: ns,
    71  			Name:      podName,
    72  		},
    73  		Spec: v1.PodSpec{},
    74  	}
    75  	for i, configMaps := range toAttach.containerEnvConfigMaps {
    76  		container := v1.Container{
    77  			Name: fmt.Sprintf("container-%d", i),
    78  		}
    79  		for _, name := range configMaps.envFromNames {
    80  			envFrom := v1.EnvFromSource{
    81  				ConfigMapRef: &v1.ConfigMapEnvSource{
    82  					LocalObjectReference: v1.LocalObjectReference{
    83  						Name: name,
    84  					},
    85  				},
    86  			}
    87  			container.EnvFrom = append(container.EnvFrom, envFrom)
    88  		}
    89  
    90  		for _, name := range configMaps.envVarNames {
    91  			envSource := &v1.EnvVarSource{
    92  				ConfigMapKeyRef: &v1.ConfigMapKeySelector{
    93  					LocalObjectReference: v1.LocalObjectReference{
    94  						Name: name,
    95  					},
    96  				},
    97  			}
    98  			container.Env = append(container.Env, v1.EnvVar{ValueFrom: envSource})
    99  		}
   100  		pod.Spec.Containers = append(pod.Spec.Containers, container)
   101  	}
   102  	for _, configMap := range toAttach.volumes {
   103  		volume := &v1.ConfigMapVolumeSource{
   104  			LocalObjectReference: v1.LocalObjectReference{Name: configMap},
   105  		}
   106  		pod.Spec.Volumes = append(pod.Spec.Volumes, v1.Volume{
   107  			Name: configMap,
   108  			VolumeSource: v1.VolumeSource{
   109  				ConfigMap: volume,
   110  			},
   111  		})
   112  	}
   113  	return pod
   114  }
   115  
   116  func TestCacheBasedConfigMapManager(t *testing.T) {
   117  	fakeClient := &fake.Clientset{}
   118  	store := manager.NewObjectStore(getConfigMap(fakeClient), clock.RealClock{}, noObjectTTL, 0)
   119  	manager := &configMapManager{
   120  		manager: manager.NewCacheBasedManager(store, getConfigMapNames),
   121  	}
   122  
   123  	// Create a pod with some configMaps.
   124  	s1 := configMapsToAttach{
   125  		containerEnvConfigMaps: []envConfigMaps{
   126  			{envVarNames: []string{"s1"}},
   127  			{envFromNames: []string{"s20"}},
   128  		},
   129  		volumes: []string{"s2"},
   130  	}
   131  	manager.RegisterPod(podWithConfigMaps("ns1", "name1", s1))
   132  	manager.RegisterPod(podWithConfigMaps("ns2", "name2", s1))
   133  	// Update the pod with a different configMaps.
   134  	s2 := configMapsToAttach{
   135  		containerEnvConfigMaps: []envConfigMaps{
   136  			{envVarNames: []string{"s3"}},
   137  			{envVarNames: []string{"s4"}},
   138  			{envFromNames: []string{"s40"}},
   139  		},
   140  	}
   141  	// Create another pod, but with same configMaps in different namespace.
   142  	manager.RegisterPod(podWithConfigMaps("ns2", "name2", s2))
   143  	// Create and delete a pod with some other configMaps.
   144  	s3 := configMapsToAttach{
   145  		containerEnvConfigMaps: []envConfigMaps{
   146  			{envVarNames: []string{"s6"}},
   147  			{envFromNames: []string{"s60"}},
   148  		},
   149  	}
   150  	manager.RegisterPod(podWithConfigMaps("ns3", "name", s3))
   151  	manager.UnregisterPod(podWithConfigMaps("ns3", "name", s3))
   152  
   153  	existingMaps := map[string][]string{
   154  		"ns1": {"s1", "s2", "s20"},
   155  		"ns2": {"s3", "s4", "s40"},
   156  	}
   157  	shouldExist := func(ns, configMap string) bool {
   158  		if cmaps, ok := existingMaps[ns]; ok {
   159  			for _, cm := range cmaps {
   160  				if cm == configMap {
   161  					return true
   162  				}
   163  			}
   164  		}
   165  		return false
   166  	}
   167  
   168  	for _, ns := range []string{"ns1", "ns2", "ns3"} {
   169  		for _, configMap := range []string{"s1", "s2", "s3", "s4", "s5", "s6", "s20", "s40", "s50"} {
   170  			checkObject(t, store, ns, configMap, shouldExist(ns, configMap))
   171  		}
   172  	}
   173  }
   174  

View as plain text