// 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}
}
예제 #2
0
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))
	}
}
예제 #3
0
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)
	}
}
예제 #4
0
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)
		}
	}
}
예제 #5
0
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")
	}
}
예제 #6
0
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)
	}
}