...

Source file src/github.com/datawire/ambassador/v2/pkg/agent/k8s_test.go

Documentation: github.com/datawire/ambassador/v2/pkg/agent

     1  package agent_test
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  
     7  	"github.com/stretchr/testify/assert"
     8  	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
     9  	"k8s.io/apimachinery/pkg/runtime/schema"
    10  	"k8s.io/client-go/dynamic"
    11  	"k8s.io/client-go/tools/cache"
    12  
    13  	"github.com/datawire/ambassador/v2/pkg/agent"
    14  	"github.com/datawire/dlib/dlog"
    15  )
    16  
    17  type informerMock struct {
    18  	eventHandler cache.ResourceEventHandler
    19  	run          func(handler cache.ResourceEventHandler)
    20  }
    21  
    22  func (i *informerMock) AddEventHandler(handler cache.ResourceEventHandler) {
    23  	i.eventHandler = handler
    24  
    25  }
    26  func (i *informerMock) Run(stopCh <-chan struct{}) {
    27  	i.run(i.eventHandler)
    28  }
    29  
    30  func (i *informerMock) ListCache() []interface{} {
    31  	return nil
    32  }
    33  
    34  func newInformerMock(run func(handler cache.ResourceEventHandler)) *informerMock {
    35  	return &informerMock{
    36  		run: run,
    37  	}
    38  }
    39  
    40  func (i *informerMock) fakeInformer(di dynamic.Interface, ns string, gvr *schema.GroupVersionResource) agent.Informer {
    41  	return i
    42  }
    43  
    44  func TestWatchGeneric(t *testing.T) {
    45  	type runFunc func(handler cache.ResourceEventHandler)
    46  	type fixture struct {
    47  		dc         *agent.DynamicClient
    48  		rolloutGvr *schema.GroupVersionResource
    49  	}
    50  	defaultRunFunc := func(handler cache.ResourceEventHandler) {
    51  		obj := &unstructured.Unstructured{}
    52  		obj.SetName("obj1-added")
    53  		handler.OnAdd(obj)
    54  
    55  		objNew := &unstructured.Unstructured{}
    56  		objNew.SetName("obj1-new")
    57  		handler.OnUpdate(obj, objNew)
    58  
    59  		objDel := &unstructured.Unstructured{}
    60  		objDel.SetName("obj1-del")
    61  		handler.OnDelete(objDel)
    62  	}
    63  	setup := func(runFunc runFunc) *fixture {
    64  		rf := defaultRunFunc
    65  		if runFunc != nil {
    66  			rf = runFunc
    67  		}
    68  		mock := newInformerMock(rf)
    69  		dc := agent.NewDynamicClient(nil, mock.fakeInformer)
    70  		rolloutGvr, _ := schema.ParseResourceArg("rollouts.v1alpha1.argoproj.io")
    71  		return &fixture{
    72  			dc:         dc,
    73  			rolloutGvr: rolloutGvr,
    74  		}
    75  
    76  	}
    77  	t.Run("will watch generic resource successfully", func(t *testing.T) {
    78  		// given
    79  		t.Parallel()
    80  		ctx := dlog.NewTestContext(t, false)
    81  		f := setup(nil)
    82  
    83  		// when
    84  		rolloutCallback := f.dc.WatchGeneric(ctx, "default", f.rolloutGvr)
    85  
    86  		// then
    87  		assert.NotNil(t, rolloutCallback)
    88  		for i := 0; i < 3; i++ {
    89  			select {
    90  			case callback := <-rolloutCallback:
    91  				switch callback.EventType {
    92  				case agent.CallbackEventAdded:
    93  					assert.Equal(t, "obj1-added", callback.Obj.GetName())
    94  				case agent.CallbackEventUpdated:
    95  					assert.Equal(t, "obj1-new", callback.Obj.GetName())
    96  				case agent.CallbackEventDeleted:
    97  					assert.Equal(t, "obj1-del", callback.Obj.GetName())
    98  				}
    99  			}
   100  		}
   101  	})
   102  	t.Run("will handle context cancelation gracefully", func(t *testing.T) {
   103  		// given
   104  		t.Parallel()
   105  		informerRunFunc := func(handler cache.ResourceEventHandler) {
   106  			obj := &unstructured.Unstructured{}
   107  			obj.SetName("obj1-added")
   108  			handler.OnAdd(obj)
   109  		}
   110  		ctx, cancel := context.WithCancel(dlog.NewTestContext(t, false))
   111  		cancel()
   112  		f := setup(informerRunFunc)
   113  
   114  		// when
   115  		rolloutCallback := f.dc.WatchGeneric(ctx, "default", f.rolloutGvr)
   116  
   117  		// then
   118  		assert.NotNil(t, rolloutCallback)
   119  		callback, ok := <-rolloutCallback
   120  		if ok {
   121  			assert.NotNil(t, callback)
   122  			assert.Equal(t, "obj1-added", callback.Obj.GetName())
   123  		} else {
   124  			assert.Nil(t, callback)
   125  		}
   126  	})
   127  }
   128  

View as plain text