...

Source file src/edge-infra.dev/pkg/edge/info/watch_test.go

Documentation: edge-infra.dev/pkg/edge/info

     1  package info_test
     2  
     3  import (
     4  	"testing"
     5  	"time"
     6  
     7  	"github.com/stretchr/testify/assert"
     8  	corev1 "k8s.io/api/core/v1"
     9  	"k8s.io/apimachinery/pkg/types"
    10  	"sigs.k8s.io/controller-runtime/pkg/client/fake"
    11  
    12  	"edge-infra.dev/pkg/edge/info"
    13  	fakeinfo "edge-infra.dev/pkg/edge/info/fake"
    14  	"edge-infra.dev/pkg/lib/logging"
    15  	"edge-infra.dev/test/f2"
    16  )
    17  
    18  var (
    19  	waitForCallbackFunction = 200 * time.Millisecond
    20  )
    21  
    22  func TestWatchFunctions(t *testing.T) {
    23  	feature := f2.NewFeature("Test Watch Functions").
    24  		Test("OnConfigMapUpdate", func(ctx f2.Context, t *testing.T) f2.Context {
    25  			cl := fake.NewClientBuilder().Build()
    26  
    27  			updatedStoreName := "foo1"
    28  
    29  			configMap := fakeinfo.GetEdgeInfoConfigMap()
    30  			// Create an expected cm so we can use it to assert in the OnConfigMapUpdate function.
    31  			// It matches the cm that is updated later in the test after we read it back.
    32  			expectedUpdatedCM := fakeinfo.GetEdgeInfoConfigMap()
    33  			expectedUpdatedCM.Data[info.StoreName] = updatedStoreName
    34  
    35  			// create ConfigMap watch
    36  			callCount := 0
    37  			logger := logging.NewLogger().WithName("TestOnConfigMapUpdate")
    38  			watch, err := info.OnConfigMapUpdate(ctx, cl, logger, func(i *info.EdgeInfo) {
    39  				assert.NotNil(t, configMap)
    40  				if callCount == 0 {
    41  					assert.Equal(t, info.FromConfigMap(configMap), i)
    42  				} else {
    43  					assert.Equal(t, info.FromConfigMap(expectedUpdatedCM), i)
    44  				}
    45  				callCount++
    46  			})
    47  			assert.NoError(t, err)
    48  			defer watch.Stop()
    49  			assert.NoError(t, cl.Create(ctx, configMap))
    50  
    51  			time.Sleep(waitForCallbackFunction) // wait for async call
    52  
    53  			// We need to read the configmap after the cm create to be able to update it,
    54  			// otherwise it will fail with Operation cannot be fulfilled on configmaps "edge-info": object was modified
    55  			//  due to not having the most recent object data.
    56  			readCM := corev1.ConfigMap{}
    57  			err = cl.Get(ctx, types.NamespacedName{
    58  				Name:      info.EdgeConfigMapName,
    59  				Namespace: info.EdgeConfigMapNS,
    60  			}, &readCM)
    61  			assert.NoError(t, err)
    62  
    63  			readCM.Data[info.StoreName] = updatedStoreName
    64  
    65  			assert.NoError(t, cl.Update(ctx, &readCM))
    66  			time.Sleep(waitForCallbackFunction)
    67  			assert.Equal(t, 2, callCount)
    68  
    69  			return ctx
    70  		}).
    71  		Test("OnConfigMapUpdateInvalid", func(ctx f2.Context, t *testing.T) f2.Context {
    72  			cl := fake.NewClientBuilder().Build()
    73  
    74  			configMap := fakeinfo.GetEdgeInfoConfigMap()
    75  
    76  			// create ConfigMap watch
    77  			callCount := 0
    78  			logger := logging.NewLogger().WithName("TestOnConfigMapUpdateInvalid")
    79  			watch, err := info.OnConfigMapUpdate(ctx, cl, logger, func(i *info.EdgeInfo) {
    80  				assert.NotNil(t, configMap)
    81  				assert.Equal(t, info.FromConfigMap(configMap), i)
    82  				callCount++
    83  			})
    84  			assert.NoError(t, err)
    85  			defer watch.Stop()
    86  
    87  			assert.NoError(t, cl.Create(ctx, configMap))
    88  			time.Sleep(waitForCallbackFunction) // wait for async call
    89  
    90  			readCM := corev1.ConfigMap{}
    91  			err = cl.Get(ctx, types.NamespacedName{
    92  				Name:      info.EdgeConfigMapName,
    93  				Namespace: info.EdgeConfigMapNS,
    94  			}, &readCM)
    95  			assert.NoError(t, err)
    96  
    97  			delete(readCM.Data, info.StoreName)
    98  
    99  			assert.NoError(t, cl.Update(ctx, &readCM))
   100  			time.Sleep(waitForCallbackFunction)
   101  			assert.Equal(t, 1, callCount)
   102  
   103  			return ctx
   104  		}).
   105  		Test("OnConfigMapUpdateFilterMatchAll", func(ctx f2.Context, t *testing.T) f2.Context { // nolint: dupl
   106  			cl := fake.NewClientBuilder().Build()
   107  
   108  			configMap := fakeinfo.GetEdgeInfoConfigMap()
   109  			updatedConfigmap := fakeinfo.GetEdgeInfoConfigMap()
   110  			newStoreName := "updated-store-name"
   111  			newCluster := "new-id"
   112  			updatedConfigmap.Data[info.StoreName] = newStoreName
   113  			updatedConfigmap.Data[info.ClusterEdgeID] = newCluster
   114  
   115  			// create ConfigMap watch
   116  			callCount := 0
   117  			logger := logging.NewLogger().WithName("TestOnConfigMapUpdateFilterMatchAll")
   118  			watch, err := info.OnConfigMapUpdate(ctx, cl, logger, func(i *info.EdgeInfo) {
   119  				assert.NotNil(t, configMap)
   120  				if callCount == 0 {
   121  					assert.Equal(t, info.FromConfigMap(configMap), i)
   122  				} else {
   123  					assert.Equal(t, info.FromConfigMap(updatedConfigmap), i)
   124  				}
   125  				callCount++
   126  			}, info.StoreName, info.ClusterEdgeID)
   127  			assert.NoError(t, err)
   128  			defer watch.Stop()
   129  
   130  			assert.NoError(t, cl.Create(ctx, configMap))
   131  			time.Sleep(waitForCallbackFunction)
   132  
   133  			readCM := corev1.ConfigMap{}
   134  			err = cl.Get(ctx, types.NamespacedName{
   135  				Name:      info.EdgeConfigMapName,
   136  				Namespace: info.EdgeConfigMapNS,
   137  			}, &readCM)
   138  			assert.NoError(t, err)
   139  
   140  			readCM.Data[info.StoreName] = newStoreName
   141  			readCM.Data[info.ClusterEdgeID] = newCluster
   142  
   143  			assert.NoError(t, cl.Update(ctx, &readCM))
   144  			time.Sleep(waitForCallbackFunction)
   145  			assert.Equal(t, 2, callCount)
   146  
   147  			return ctx
   148  		}).
   149  		Test("OnConfigMapUpdateFilterMatchOne", func(ctx f2.Context, t *testing.T) f2.Context { // nolint: dupl
   150  			cl := fake.NewClientBuilder().Build()
   151  
   152  			configMap := fakeinfo.GetEdgeInfoConfigMap()
   153  			updatedConfigmap := fakeinfo.GetEdgeInfoConfigMap()
   154  			newStore := "foo3"
   155  			newLoc := "new-location"
   156  			updatedConfigmap.Data[info.StoreName] = newStore
   157  			updatedConfigmap.Data[info.K8sClusterLocation] = newLoc
   158  
   159  			// create ConfigMap watch
   160  			callCount := 0
   161  			logger := logging.NewLogger().WithName("TestOnConfigMapUpdateFilterMatchOne")
   162  			watch, err := info.OnConfigMapUpdate(ctx, cl, logger, func(i *info.EdgeInfo) {
   163  				assert.NotNil(t, configMap)
   164  				if callCount == 0 {
   165  					assert.Equal(t, info.FromConfigMap(configMap), i)
   166  				} else {
   167  					assert.Equal(t, info.FromConfigMap(updatedConfigmap), i)
   168  				}
   169  				callCount++
   170  			}, info.StoreName, info.ClusterEdgeID)
   171  			assert.NoError(t, err)
   172  			defer watch.Stop()
   173  
   174  			assert.NoError(t, cl.Create(ctx, configMap))
   175  			time.Sleep(waitForCallbackFunction)
   176  
   177  			readCM := corev1.ConfigMap{}
   178  			err = cl.Get(ctx, types.NamespacedName{
   179  				Name:      info.EdgeConfigMapName,
   180  				Namespace: info.EdgeConfigMapNS,
   181  			}, &readCM)
   182  			assert.NoError(t, err)
   183  
   184  			readCM.Data[info.StoreName] = newStore
   185  			readCM.Data[info.K8sClusterLocation] = newLoc
   186  
   187  			assert.NoError(t, cl.Update(ctx, &readCM))
   188  			time.Sleep(waitForCallbackFunction)
   189  			assert.Equal(t, 2, callCount)
   190  
   191  			return ctx
   192  		}).
   193  		Test("OnConfigMapUpdateFilterMatchNone", func(ctx f2.Context, t *testing.T) f2.Context {
   194  			cl := fake.NewClientBuilder().Build()
   195  
   196  			configMap := fakeinfo.GetEdgeInfoConfigMap()
   197  			updatedConfigmap := fakeinfo.GetEdgeInfoConfigMap()
   198  			storeName := "foo4"
   199  			updatedConfigmap.Data[info.StoreName] = storeName
   200  
   201  			// create ConfigMap watch
   202  			callCount := 0
   203  			logger := logging.NewLogger().WithName("TestOnConfigMapUpdateFilterMatchNone")
   204  			watch, err := info.OnConfigMapUpdate(ctx, cl, logger, func(i *info.EdgeInfo) {
   205  				assert.NotNil(t, configMap)
   206  				assert.Equal(t, info.FromConfigMap(configMap), i)
   207  				callCount++
   208  			}, info.ClusterEdgeID, info.ProjectID)
   209  			assert.NoError(t, err)
   210  			defer watch.Stop()
   211  
   212  			assert.NoError(t, cl.Create(ctx, configMap))
   213  			time.Sleep(waitForCallbackFunction) // wait for async call
   214  
   215  			readCM := corev1.ConfigMap{}
   216  			err = cl.Get(ctx, types.NamespacedName{
   217  				Name:      info.EdgeConfigMapName,
   218  				Namespace: info.EdgeConfigMapNS,
   219  			}, &readCM)
   220  			assert.NoError(t, err)
   221  
   222  			readCM.Data[info.StoreName] = storeName
   223  
   224  			assert.NoError(t, cl.Update(ctx, &readCM))
   225  			time.Sleep(waitForCallbackFunction)
   226  			assert.Equal(t, 1, callCount)
   227  
   228  			return ctx
   229  		}).Feature()
   230  	f.Test(t, feature)
   231  }
   232  

View as plain text