fix the fake client example: how to handle a race between the fake client and informer
Note that the fake client isn't designed to work with informer. It doesn't support resource version. It's encouraged to use a real client in an integration/E2E test if you need to test complex behavior with informer/controllers.
This commit is contained in:
		@@ -21,11 +21,13 @@ import (
 | 
			
		||||
	"testing"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"k8s.io/api/core/v1"
 | 
			
		||||
	v1 "k8s.io/api/core/v1"
 | 
			
		||||
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
			
		||||
	"k8s.io/apimachinery/pkg/util/wait"
 | 
			
		||||
	"k8s.io/apimachinery/pkg/watch"
 | 
			
		||||
	"k8s.io/client-go/informers"
 | 
			
		||||
	"k8s.io/client-go/kubernetes/fake"
 | 
			
		||||
	clienttesting "k8s.io/client-go/testing"
 | 
			
		||||
	"k8s.io/client-go/tools/cache"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@@ -34,8 +36,20 @@ func TestFakeClient(t *testing.T) {
 | 
			
		||||
	ctx, cancel := context.WithCancel(context.Background())
 | 
			
		||||
	defer cancel()
 | 
			
		||||
 | 
			
		||||
	watcherStarted := make(chan struct{})
 | 
			
		||||
	// Create the fake client.
 | 
			
		||||
	client := fake.NewSimpleClientset()
 | 
			
		||||
	// A catch-all watch reactor that allows us to inject the watcherStarted channel.
 | 
			
		||||
	client.PrependWatchReactor("*", func(action clienttesting.Action) (handled bool, ret watch.Interface, err error) {
 | 
			
		||||
		gvr := action.GetResource()
 | 
			
		||||
		ns := action.GetNamespace()
 | 
			
		||||
		watch, err := client.Tracker().Watch(gvr, ns)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return false, nil, err
 | 
			
		||||
		}
 | 
			
		||||
		close(watcherStarted)
 | 
			
		||||
		return true, watch, nil
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	// We will create an informer that writes added pods to a channel.
 | 
			
		||||
	pods := make(chan *v1.Pod, 1)
 | 
			
		||||
@@ -57,6 +71,15 @@ func TestFakeClient(t *testing.T) {
 | 
			
		||||
	// we send any events to it.
 | 
			
		||||
	cache.WaitForCacheSync(ctx.Done(), podInformer.HasSynced)
 | 
			
		||||
 | 
			
		||||
	// The fake client doesn't support resource version. Any writes to the client
 | 
			
		||||
	// after the informer's initial LIST and before the informer establishing the
 | 
			
		||||
	// watcher will be missed by the informer. Therefore we wait until the watcher
 | 
			
		||||
	// starts.
 | 
			
		||||
	// Note that the fake client isn't designed to work with informer. It
 | 
			
		||||
	// doesn't support resource version. It's encouraged to use a real client
 | 
			
		||||
	// in an integration/E2E test if you need to test complex behavior with
 | 
			
		||||
	// informer/controllers.
 | 
			
		||||
	<-watcherStarted
 | 
			
		||||
	// Inject an event into the fake client.
 | 
			
		||||
	p := &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "my-pod"}}
 | 
			
		||||
	_, err := client.CoreV1().Pods("test-ns").Create(context.TODO(), p, metav1.CreateOptions{})
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user