// NewSimpleClientset returns a clientset that will respond with the provided objects. // It's backed by a very simple object tracker that processes creates, updates and deletions as-is, // without applying any validations and/or defaults. It shouldn't be considered a replacement // for a real clientset and is mostly useful in simple unit tests. func NewSimpleClientset(objects ...runtime.Object) *Clientset { o := core.NewObjectTracker(api.Scheme, api.Codecs.UniversalDecoder()) for _, obj := range objects { if err := o.Add(obj); err != nil { panic(err) } } fakePtr := core.Fake{} fakePtr.AddReactor("*", "*", core.ObjectReaction(o, registered.RESTMapper())) fakePtr.AddWatchReactor("*", core.DefaultWatchReactor(watch.NewFake(), nil)) return &Clientset{fakePtr} }
func TestNewSourceApiserver_TwoNamespacesSameName(t *testing.T) { pod1 := api.Pod{ ObjectMeta: api.ObjectMeta{Name: "p", Namespace: "one"}, Spec: api.PodSpec{Containers: []api.Container{{Image: "image/one"}}}} pod2 := api.Pod{ ObjectMeta: api.ObjectMeta{Name: "p", Namespace: "two"}, Spec: api.PodSpec{Containers: []api.Container{{Image: "image/blah"}}}} // Setup fake api client. fakeWatch := watch.NewFake() lw := fakePodLW{ listResp: &api.PodList{Items: []api.Pod{pod1, pod2}}, watchResp: fakeWatch, } ch := make(chan interface{}) newSourceApiserverFromLW(lw, ch) got, ok := <-ch if !ok { t.Errorf("Unable to read from channel when expected") } update := got.(kubetypes.PodUpdate) // Make sure that we get both pods. Catches bug #2294. if !(len(update.Pods) == 2) { t.Errorf("Expected %d, Got %d", 2, len(update.Pods)) } // Delete pod1 fakeWatch.Delete(&pod1) got, ok = <-ch if !ok { t.Errorf("Unable to read from channel when expected") } update = got.(kubetypes.PodUpdate) if !(len(update.Pods) == 1) { t.Errorf("Expected %d, Got %d", 1, len(update.Pods)) } }
func TestNewSourceApiserverInitialEmptySendsEmptyPodUpdate(t *testing.T) { // Setup fake api client. fakeWatch := watch.NewFake() lw := fakePodLW{ listResp: &api.PodList{Items: []api.Pod{}}, watchResp: fakeWatch, } ch := make(chan interface{}) newSourceApiserverFromLW(lw, ch) got, ok := <-ch if !ok { t.Errorf("Unable to read from channel when expected") } update := got.(kubetypes.PodUpdate) expected := CreatePodUpdate(kubetypes.SET, kubetypes.ApiserverSource) if !api.Semantic.DeepEqual(expected, update) { t.Errorf("Expected %#v; Got %#v", expected, update) } }
func TestReflectorForWatchCache(t *testing.T) { store := newTestWatchCache(5) { _, version, err := store.WaitUntilFreshAndList(0) if err != nil { t.Fatalf("unexpected error: %v", err) } if version != 0 { t.Errorf("unexpected resource version: %d", version) } } lw := &testLW{ WatchFunc: func(options api.ListOptions) (watch.Interface, error) { fw := watch.NewFake() go fw.Stop() return fw, nil }, ListFunc: func(options api.ListOptions) (runtime.Object, error) { return &api.PodList{ListMeta: unversioned.ListMeta{ResourceVersion: "10"}}, nil }, } r := cache.NewReflector(lw, &api.Pod{}, store, 0) r.ListAndWatch(wait.NeverStop) { _, version, err := store.WaitUntilFreshAndList(10) if err != nil { t.Fatalf("unexpected error: %v", err) } if version != 10 { t.Errorf("unexpected resource version: %d", version) } } }
func TestWatchHTTPTimeout(t *testing.T) { watcher := watch.NewFake() timeoutCh := make(chan time.Time) done := make(chan struct{}) serializer, ok := api.Codecs.StreamingSerializerForMediaType("application/json", nil) if !ok { t.Fatal(serializer) } // Setup a new watchserver watchServer := &WatchServer{ watching: watcher, mediaType: "testcase/json", framer: serializer.Framer, encoder: newCodec, embeddedEncoder: newCodec, fixup: func(obj runtime.Object) {}, t: &fakeTimeoutFactory{timeoutCh, done}, } s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { watchServer.ServeHTTP(w, req) })) defer s.Close() // Setup a client dest, _ := url.Parse(s.URL) dest.Path = "/" + prefix + "/" + newGroupVersion.Group + "/" + newGroupVersion.Version + "/simple" dest.RawQuery = "watch=true" req, _ := http.NewRequest("GET", dest.String(), nil) client := http.Client{} resp, err := client.Do(req) watcher.Add(&apiservertesting.Simple{TypeMeta: unversioned.TypeMeta{APIVersion: newGroupVersion.String()}}) // Make sure we can actually watch an endpoint decoder := json.NewDecoder(resp.Body) var got watchJSON err = decoder.Decode(&got) if err != nil { t.Fatalf("Unexpected error: %v", err) } // Timeout and check for leaks close(timeoutCh) select { case <-done: if !watcher.Stopped { t.Errorf("Leaked watch on timeout") } case <-time.After(wait.ForeverTestTimeout): t.Errorf("Failed to stop watcher after %s of timeout signal", wait.ForeverTestTimeout.String()) } // Make sure we can't receive any more events through the timeout watch err = decoder.Decode(&got) if err != io.EOF { t.Errorf("Unexpected non-error") } }
func TestNewSourceApiserver_UpdatesAndMultiplePods(t *testing.T) { pod1v1 := &api.Pod{ ObjectMeta: api.ObjectMeta{Name: "p"}, Spec: api.PodSpec{Containers: []api.Container{{Image: "image/one"}}}} pod1v2 := &api.Pod{ ObjectMeta: api.ObjectMeta{Name: "p"}, Spec: api.PodSpec{Containers: []api.Container{{Image: "image/two"}}}} pod2 := &api.Pod{ ObjectMeta: api.ObjectMeta{Name: "q"}, Spec: api.PodSpec{Containers: []api.Container{{Image: "image/blah"}}}} // Setup fake api client. fakeWatch := watch.NewFake() lw := fakePodLW{ listResp: &api.PodList{Items: []api.Pod{*pod1v1}}, watchResp: fakeWatch, } ch := make(chan interface{}) newSourceApiserverFromLW(lw, ch) got, ok := <-ch if !ok { t.Errorf("Unable to read from channel when expected") } update := got.(kubetypes.PodUpdate) expected := CreatePodUpdate(kubetypes.SET, kubetypes.ApiserverSource, pod1v1) if !api.Semantic.DeepEqual(expected, update) { t.Errorf("Expected %#v; Got %#v", expected, update) } // Add another pod fakeWatch.Add(pod2) got, ok = <-ch if !ok { t.Errorf("Unable to read from channel when expected") } update = got.(kubetypes.PodUpdate) // Could be sorted either of these two ways: expectedA := CreatePodUpdate(kubetypes.SET, kubetypes.ApiserverSource, pod1v1, pod2) expectedB := CreatePodUpdate(kubetypes.SET, kubetypes.ApiserverSource, pod2, pod1v1) if !api.Semantic.DeepEqual(expectedA, update) && !api.Semantic.DeepEqual(expectedB, update) { t.Errorf("Expected %#v or %#v, Got %#v", expectedA, expectedB, update) } // Modify pod1 fakeWatch.Modify(pod1v2) got, ok = <-ch if !ok { t.Errorf("Unable to read from channel when expected") } update = got.(kubetypes.PodUpdate) expectedA = CreatePodUpdate(kubetypes.SET, kubetypes.ApiserverSource, pod1v2, pod2) expectedB = CreatePodUpdate(kubetypes.SET, kubetypes.ApiserverSource, pod2, pod1v2) if !api.Semantic.DeepEqual(expectedA, update) && !api.Semantic.DeepEqual(expectedB, update) { t.Errorf("Expected %#v or %#v, Got %#v", expectedA, expectedB, update) } // Delete pod1 fakeWatch.Delete(pod1v2) got, ok = <-ch if !ok { t.Errorf("Unable to read from channel when expected") } update = got.(kubetypes.PodUpdate) expected = CreatePodUpdate(kubetypes.SET, kubetypes.ApiserverSource, pod2) if !api.Semantic.DeepEqual(expected, update) { t.Errorf("Expected %#v, Got %#v", expected, update) } // Delete pod2 fakeWatch.Delete(pod2) got, ok = <-ch if !ok { t.Errorf("Unable to read from channel when expected") } update = got.(kubetypes.PodUpdate) expected = CreatePodUpdate(kubetypes.SET, kubetypes.ApiserverSource) if !api.Semantic.DeepEqual(expected, update) { t.Errorf("Expected %#v, Got %#v", expected, update) } }