Example #1
0
func watchBody(codec runtime.Codec, events []watch.Event) io.ReadCloser {
	buf := bytes.NewBuffer([]byte{})
	enc := json.NewEncoder(buf, codec)
	for i := range events {
		enc.Encode(&events[i])
	}
	return ioutil.NopCloser(buf)
}
Example #2
0
func watchBody(events ...watch.Event) string {
	buf := &bytes.Buffer{}
	enc := watchjson.NewEncoder(buf, testapi.Default.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 := watchjson.NewEncoder(w, 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()
		}
	}))
	// TODO: Uncomment when fix #19254
	// 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")
	}
}
Example #4
0
// ServeHTTP serves a series of JSON encoded events via straight HTTP with
// Transfer-Encoding: chunked.
func (self *WatchServer) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	loggedW := httplog.LogOf(req, w)
	w = httplog.Unlogged(w)
	timeoutCh, cleanup := self.t.TimeoutCh()
	defer cleanup()
	defer self.watching.Stop()

	cn, ok := w.(http.CloseNotifier)
	if !ok {
		loggedW.Addf("unable to get CloseNotifier: %#v", w)
		http.NotFound(w, req)
		return
	}
	flusher, ok := w.(http.Flusher)
	if !ok {
		loggedW.Addf("unable to get Flusher: %#v", w)
		http.NotFound(w, req)
		return
	}
	w.Header().Set("Transfer-Encoding", "chunked")
	w.WriteHeader(http.StatusOK)
	flusher.Flush()
	// TODO: use arbitrary serialization on watch
	encoder := watchjson.NewEncoder(w, self.encoder)
	for {
		select {
		case <-cn.CloseNotify():
			return
		case <-timeoutCh:
			return
		case event, ok := <-self.watching.ResultChan():
			if !ok {
				// End of results.
				return
			}
			self.fixup(event.Object)
			if err := encoder.Encode(&event); err != nil {
				// Client disconnect.
				return
			}
			flusher.Flush()
		}
	}
}
Example #5
0
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"}}},
	}

	auth := &Config{Username: "******", Password: "******"}
	testServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		checkAuth(t, auth, r)
		flusher, ok := w.(http.Flusher)
		if !ok {
			panic("need flusher!")
		}

		w.Header().Set("Transfer-Encoding", "chunked")
		w.WriteHeader(http.StatusOK)
		flusher.Flush()

		encoder := watchjson.NewEncoder(w, latest.Codec)
		for _, item := range table {
			if err := encoder.Encode(&watch.Event{item.t, item.obj}); err != nil {
				panic(err)
			}
			flusher.Flush()
		}
	}))

	s, err := New(&Config{
		Host:     testServer.URL,
		Version:  testapi.Version(),
		Username: "******",
		Password: "******",
	})
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	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")
	}
}
Example #6
0
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 := watchjson.NewEncoder(w, 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)
			}
		}
	}
}