mirror of
https://github.com/kubernetes/client-go.git
synced 2025-08-08 02:44:20 +00:00
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. Kubernetes-commit: 942bc9b32e39bb9c6ca045c02b48cc84dfa86633
This commit is contained in:
parent
67a7335497
commit
7dddf976b8
@ -21,11 +21,13 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/util/wait"
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
|
"k8s.io/apimachinery/pkg/watch"
|
||||||
"k8s.io/client-go/informers"
|
"k8s.io/client-go/informers"
|
||||||
"k8s.io/client-go/kubernetes/fake"
|
"k8s.io/client-go/kubernetes/fake"
|
||||||
|
clienttesting "k8s.io/client-go/testing"
|
||||||
"k8s.io/client-go/tools/cache"
|
"k8s.io/client-go/tools/cache"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -34,8 +36,20 @@ func TestFakeClient(t *testing.T) {
|
|||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
|
watcherStarted := make(chan struct{})
|
||||||
// Create the fake client.
|
// Create the fake client.
|
||||||
client := fake.NewSimpleClientset()
|
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.
|
// We will create an informer that writes added pods to a channel.
|
||||||
pods := make(chan *v1.Pod, 1)
|
pods := make(chan *v1.Pod, 1)
|
||||||
@ -57,6 +71,15 @@ func TestFakeClient(t *testing.T) {
|
|||||||
// we send any events to it.
|
// we send any events to it.
|
||||||
cache.WaitForCacheSync(ctx.Done(), podInformer.HasSynced)
|
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.
|
// Inject an event into the fake client.
|
||||||
p := &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "my-pod"}}
|
p := &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "my-pod"}}
|
||||||
_, err := client.CoreV1().Pods("test-ns").Create(context.TODO(), p, metav1.CreateOptions{})
|
_, err := client.CoreV1().Pods("test-ns").Create(context.TODO(), p, metav1.CreateOptions{})
|
||||||
|
Loading…
Reference in New Issue
Block a user