func watchBody(codec runtime.Codec, events []watch.Event) io.ReadCloser { buf := bytes.NewBuffer([]byte{}) enc := versioned.NewEncoder(streaming.NewEncoder(buf, codec), codec) for i := range events { enc.Encode(&events[i]) } return json.Framer.NewFrameReader(ioutil.NopCloser(buf)) }
func watchBody(events ...watch.Event) string { buf := &bytes.Buffer{} codec := testapi.Default.Codec() enc := versioned.NewEncoder(streaming.NewEncoder(buf, codec), codec) for _, e := range events { enc.Encode(&e) } return buf.String() }
func TestWatch(t *testing.T) { var table = []struct { t watch.EventType obj runtime.Object }{ {watch.Added, &api.Pod{ObjectMeta: api.ObjectMeta{Name: "first"}}}, {watch.Modified, &api.Pod{ObjectMeta: api.ObjectMeta{Name: "second"}}}, {watch.Deleted, &api.Pod{ObjectMeta: api.ObjectMeta{Name: "last"}}}, } testServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { flusher, ok := w.(http.Flusher) if !ok { panic("need flusher!") } w.Header().Set("Transfer-Encoding", "chunked") w.WriteHeader(http.StatusOK) flusher.Flush() encoder := versioned.NewEncoder(streaming.NewEncoder(w, testapi.Default.Codec()), testapi.Default.Codec()) for _, item := range table { if err := encoder.Encode(&watch.Event{Type: item.t, Object: item.obj}); err != nil { panic(err) } flusher.Flush() } })) defer testServer.Close() s := testRESTClient(t, testServer) watching, err := s.Get().Prefix("path/to/watch/thing").Watch() if err != nil { t.Fatalf("Unexpected error") } for _, item := range table { got, ok := <-watching.ResultChan() if !ok { t.Fatalf("Unexpected early close") } if e, a := item.t, got.Type; e != a { t.Errorf("Expected %v, got %v", e, a) } if e, a := item.obj, got.Object; !api.Semantic.DeepDerivative(e, a) { t.Errorf("Expected %v, got %v", e, a) } } _, ok := <-watching.ResultChan() if ok { t.Fatal("Unexpected non-close") } }
func TestEncodeDecodeRoundTrip(t *testing.T) { testCases := []struct { Type watch.EventType Object runtime.Object Codec runtime.Codec }{ { watch.Added, &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}, testapi.Default.Codec(), }, { watch.Modified, &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}, testapi.Default.Codec(), }, { watch.Deleted, &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}, testapi.Default.Codec(), }, } for i, testCase := range testCases { buf := &bytes.Buffer{} codec := testCase.Codec encoder := versioned.NewEncoder(streaming.NewEncoder(buf, codec), codec) if err := encoder.Encode(&watch.Event{Type: testCase.Type, Object: testCase.Object}); err != nil { t.Errorf("%d: unexpected error: %v", i, err) continue } rc := ioutil.NopCloser(buf) decoder := versioned.NewDecoder(streaming.NewDecoder(rc, codec), codec) event, obj, err := decoder.Decode() if err != nil { t.Errorf("%d: unexpected error: %v", i, err) continue } if !api.Semantic.DeepDerivative(testCase.Object, obj) { t.Errorf("%d: expected %#v, got %#v", i, testCase.Object, obj) } if event != testCase.Type { t.Errorf("%d: unexpected type: %#v", i, event) } } }
func TestWatch(t *testing.T) { tcs := []struct { name string namespace string events []watch.Event path string }{ { name: "normal_watch", path: "/api/gtest/vtest/watch/rtest", events: []watch.Event{ {Type: watch.Added, Object: getObject("vTest", "rTest", "normal_watch")}, {Type: watch.Modified, Object: getObject("vTest", "rTest", "normal_watch")}, {Type: watch.Deleted, Object: getObject("vTest", "rTest", "normal_watch")}, }, }, { name: "namespaced_watch", namespace: "nstest", path: "/api/gtest/vtest/watch/namespaces/nstest/rtest", events: []watch.Event{ {Type: watch.Added, Object: getObject("vTest", "rTest", "namespaced_watch")}, {Type: watch.Modified, Object: getObject("vTest", "rTest", "namespaced_watch")}, {Type: watch.Deleted, Object: getObject("vTest", "rTest", "namespaced_watch")}, }, }, } for _, tc := range tcs { gv := &unversioned.GroupVersion{Group: "gtest", Version: "vtest"} resource := &unversioned.APIResource{Name: "rtest", Namespaced: len(tc.namespace) != 0} cl, srv, err := getClientServer(gv, func(w http.ResponseWriter, r *http.Request) { if r.Method != "GET" { t.Errorf("Watch(%q) got HTTP method %s. wanted GET", tc.name, r.Method) } if r.URL.Path != tc.path { t.Errorf("Watch(%q) got path %s. wanted %s", tc.name, r.URL.Path, tc.path) } enc := versioned.NewEncoder(streaming.NewEncoder(w, dynamicCodec{}), dynamicCodec{}) for _, e := range tc.events { enc.Encode(&e) } }) if err != nil { t.Errorf("unexpected error when creating client: %v", err) continue } defer srv.Close() watcher, err := cl.Resource(resource, tc.namespace).Watch(&v1.ListOptions{}) if err != nil { t.Errorf("unexpected error when watching %q: %v", tc.name, err) continue } for _, want := range tc.events { got := <-watcher.ResultChan() if !reflect.DeepEqual(got, want) { t.Errorf("Watch(%q) want: %v\ngot: %v", tc.name, want, got) } } } }