// mockREST mocks a DeploymentLog REST func mockREST(version, desired int, endStatus api.DeploymentStatus) *REST { // Fake deploymentConfig config := deploytest.OkDeploymentConfig(version) fakeDn := testclient.NewSimpleFake(config) fakeDn.PrependReactor("get", "deploymentconfigs", func(action ktestclient.Action) (handled bool, ret runtime.Object, err error) { return true, config, nil }) // Fake deployments fakeDeployments := makeDeploymentList(version) fakeRn := ktestclient.NewSimpleFake(fakeDeployments) fakeRn.PrependReactor("get", "replicationcontrollers", func(action ktestclient.Action) (handled bool, ret runtime.Object, err error) { return true, &fakeDeployments.Items[desired-1], nil }) // Fake watcher for deployments fakeWatch := watch.NewFake() fakeRn.PrependWatchReactor("replicationcontrollers", ktestclient.DefaultWatchReactor(fakeWatch, nil)) // Everything is fake connectionInfo := &kclient.HTTPKubeletClient{Config: &kclient.KubeletConfig{EnableHttps: true, Port: 12345}, Client: &http.Client{}} obj := &fakeDeployments.Items[desired-1] obj.Annotations[api.DeploymentStatusAnnotation] = string(endStatus) go fakeWatch.Add(obj) return &REST{ ConfigGetter: fakeDn, DeploymentGetter: fakeRn, PodGetter: &deployerPodGetter{}, ConnectionInfo: connectionInfo, Timeout: defaultTimeout, } }
func TestReflectorResync(t *testing.T) { iteration := 0 stopCh := make(chan struct{}) s := &FakeCustomStore{ ResyncFunc: func() error { iteration++ if iteration == 2 { close(stopCh) } return nil }, } lw := &testLW{ WatchFunc: func(options api.ListOptions) (watch.Interface, error) { fw := watch.NewFake() return fw, nil }, ListFunc: func() (runtime.Object, error) { return &api.PodList{ListMeta: unversioned.ListMeta{ResourceVersion: "0"}}, nil }, } resyncPeriod := 1 * time.Millisecond r := NewReflector(lw, &api.Pod{}, s, resyncPeriod) r.ListAndWatch(stopCh) if iteration != 2 { t.Errorf("exactly 2 iterations were expected, got: %v", iteration) } }
func TestReflectorForWatchCache(t *testing.T) { store := newWatchCache(5) { _, version := store.ListWithVersion() if version != 0 { t.Errorf("unexpected resource version: %d", version) } } lw := &testLW{ WatchFunc: func(rv string) (watch.Interface, error) { fw := watch.NewFake() go fw.Stop() return fw, nil }, ListFunc: func() (runtime.Object, error) { return &api.PodList{ListMeta: unversioned.ListMeta{ResourceVersion: "10"}}, nil }, } r := cache.NewReflector(lw, &api.Pod{}, store, 0) r.ListAndWatch(util.NeverStop) { _, version := store.ListWithVersion() if version != 10 { t.Errorf("unexpected resource version: %d", version) } } }
func TestRunUntil(t *testing.T) { stopCh := make(chan struct{}) store := NewStore(MetaNamespaceKeyFunc) r := NewReflector(&testLW{}, &api.Pod{}, store, 0) fw := watch.NewFake() r.listerWatcher = &testLW{ WatchFunc: func(rv string) (watch.Interface, error) { return fw, nil }, ListFunc: func() (runtime.Object, error) { return &api.PodList{ListMeta: unversioned.ListMeta{ResourceVersion: "1"}}, nil }, } r.RunUntil(stopCh) // Synchronously add a dummy pod into the watch channel so we // know the RunUntil go routine is in the watch handler. fw.Add(&api.Pod{ObjectMeta: api.ObjectMeta{Name: "bar"}}) stopCh <- struct{}{} select { case _, ok := <-fw.ResultChan(): if ok { t.Errorf("Watch channel left open after stopping the watch") } case <-time.After(util.ForeverTestTimeout): t.Errorf("the cancellation is at least %s late", util.ForeverTestTimeout.String()) break } }
func TestDecoratedWatcher(t *testing.T) { w := watch.NewFake() decorator := func(obj runtime.Object) error { pod := obj.(*api.Pod) pod.Annotations = map[string]string{"decorated": "true"} return nil } dw := newDecoratedWatcher(w, decorator) defer dw.Stop() go w.Add(&api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}) select { case e := <-dw.ResultChan(): pod, ok := e.Object.(*api.Pod) if !ok { t.Errorf("Should received object of type *api.Pod, get type (%T)", e.Object) return } if pod.Annotations["decorated"] != "true" { t.Errorf("pod.Annotations[\"decorated\"], want=%s, get=%s", "true", pod.Labels["decorated"]) } case <-time.After(wait.ForeverTestTimeout): t.Errorf("timeout after %v", wait.ForeverTestTimeout) } }
func TestReflectorResync(t *testing.T) { iteration := 0 stopCh := make(chan struct{}) rerr := errors.New("expected resync reached") s := &FakeCustomStore{ ResyncFunc: func() error { iteration++ if iteration == 2 { return rerr } return nil }, } lw := &testLW{ WatchFunc: func(options api.ListOptions) (watch.Interface, error) { fw := watch.NewFake() return fw, nil }, ListFunc: func() (runtime.Object, error) { return &api.PodList{ListMeta: unversioned.ListMeta{ResourceVersion: "0"}}, nil }, } resyncPeriod := 1 * time.Millisecond r := NewReflector(lw, &api.Pod{}, s, resyncPeriod) if err := r.ListAndWatch(stopCh); err != nil { // error from Resync is not propaged up to here. t.Errorf("expected error %v", err) } if iteration != 2 { t.Errorf("exactly 2 iterations were expected, got: %v", iteration) } }
func controllerSetup(startingObjects []runtime.Object, stopChannel chan struct{}, t *testing.T) ( /*caName*/ string, *fake.Clientset, *watch.FakeWatcher, *ServiceServingCertController) { certDir, err := ioutil.TempDir("", "serving-cert-unit-") if err != nil { t.Fatalf("unexpected error: %v", err) } caInfo := admin.DefaultServiceSignerCAInfo(certDir) caOptions := admin.CreateSignerCertOptions{ CertFile: caInfo.CertFile, KeyFile: caInfo.KeyFile, Name: admin.DefaultServiceServingCertSignerName(), Output: ioutil.Discard, } ca, err := caOptions.CreateSignerCert() if err != nil { t.Fatalf("unexpected error: %v", err) } kubeclient := fake.NewSimpleClientset(startingObjects...) fakeWatch := watch.NewFake() kubeclient.PrependReactor("create", "*", func(action core.Action) (handled bool, ret runtime.Object, err error) { return true, action.(core.CreateAction).GetObject(), nil }) kubeclient.PrependReactor("update", "*", func(action core.Action) (handled bool, ret runtime.Object, err error) { return true, action.(core.UpdateAction).GetObject(), nil }) kubeclient.PrependWatchReactor("*", core.DefaultWatchReactor(fakeWatch, nil)) controller := NewServiceServingCertController(kubeclient.Core(), kubeclient.Core(), ca, "cluster.local", 10*time.Minute) return caOptions.Name, kubeclient, fakeWatch, controller }
func TestWatchHTTPTimeout(t *testing.T) { watcher := watch.NewFake() timeoutCh := make(chan time.Time) done := make(chan struct{}) // Setup a new watchserver watchServer := &WatchServer{ watching: watcher, mediaType: "testcase/json", 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) })) // TODO: Uncomment when fix #19254 // 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 TestReflectorListAndWatch(t *testing.T) { createdFakes := make(chan *watch.FakeWatcher) // The ListFunc says that it's at revision 1. Therefore, we expect our WatchFunc // to get called at the beginning of the watch with 1, and again with 3 when we // inject an error. expectedRVs := []string{"1", "3"} lw := &testLW{ WatchFunc: func(options api.ListOptions) (watch.Interface, error) { rv := options.ResourceVersion fw := watch.NewFake() if e, a := expectedRVs[0], rv; e != a { t.Errorf("Expected rv %v, but got %v", e, a) } expectedRVs = expectedRVs[1:] // channel is not buffered because the for loop below needs to block. But // we don't want to block here, so report the new fake via a go routine. go func() { createdFakes <- fw }() return fw, nil }, ListFunc: func() (runtime.Object, error) { return &api.PodList{ListMeta: unversioned.ListMeta{ResourceVersion: "1"}}, nil }, } s := NewFIFO(MetaNamespaceKeyFunc) r := NewReflector(lw, &api.Pod{}, s, 0) go r.ListAndWatch(wait.NeverStop) ids := []string{"foo", "bar", "baz", "qux", "zoo"} var fw *watch.FakeWatcher for i, id := range ids { if fw == nil { fw = <-createdFakes } sendingRV := strconv.FormatUint(uint64(i+2), 10) fw.Add(&api.Pod{ObjectMeta: api.ObjectMeta{Name: id, ResourceVersion: sendingRV}}) if sendingRV == "3" { // Inject a failure. fw.Stop() fw = nil } } // Verify we received the right ids with the right resource versions. for i, id := range ids { pod := s.Pop().(*api.Pod) if e, a := id, pod.Name; e != a { t.Errorf("%v: Expected %v, got %v", i, e, a) } if e, a := strconv.FormatUint(uint64(i+2), 10), pod.ResourceVersion; e != a { t.Errorf("%v: Expected %v, got %v", i, e, a) } } if len(expectedRVs) != 0 { t.Error("called watchStarter an unexpected number of times") } }
func CreateTestClient() *fake.Clientset { fakeClient := &fake.Clientset{} fakeClient.AddReactor("list", "pods", func(action core.Action) (handled bool, ret runtime.Object, err error) { obj := &v1.PodList{} podNamePrefix := "mypod" namespace := "mynamespace" for i := 0; i < 5; i++ { podName := fmt.Sprintf("%s-%d", podNamePrefix, i) pod := v1.Pod{ Status: v1.PodStatus{ Phase: v1.PodRunning, }, ObjectMeta: v1.ObjectMeta{ Name: podName, Namespace: namespace, Labels: map[string]string{ "name": podName, }, }, Spec: v1.PodSpec{ Containers: []v1.Container{ { Name: "containerName", Image: "containerImage", VolumeMounts: []v1.VolumeMount{ { Name: "volumeMountName", ReadOnly: false, MountPath: "/mnt", }, }, }, }, Volumes: []v1.Volume{ { Name: "volumeName", VolumeSource: v1.VolumeSource{ GCEPersistentDisk: &v1.GCEPersistentDiskVolumeSource{ PDName: "pdName", FSType: "ext4", ReadOnly: false, }, }, }, }, }, } obj.Items = append(obj.Items, pod) } return true, obj, nil }) fakeWatch := watch.NewFake() fakeClient.AddWatchReactor("*", core.DefaultWatchReactor(fakeWatch, nil)) return fakeClient }
func TestReflectorWatchHandler(t *testing.T) { s := NewStore(MetaNamespaceKeyFunc) g := NewReflector(&testLW{}, &api.Pod{}, s, 0) fw := watch.NewFake() s.Add(&api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}) s.Add(&api.Pod{ObjectMeta: api.ObjectMeta{Name: "bar"}}) go func() { fw.Add(&api.Service{ObjectMeta: api.ObjectMeta{Name: "rejected"}}) fw.Delete(&api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}) fw.Modify(&api.Pod{ObjectMeta: api.ObjectMeta{Name: "bar", ResourceVersion: "55"}}) fw.Add(&api.Pod{ObjectMeta: api.ObjectMeta{Name: "baz", ResourceVersion: "32"}}) fw.Stop() }() var resumeRV string err := g.watchHandler(fw, &resumeRV, neverExitWatch, util.NeverStop) if err != nil { t.Errorf("unexpected error %v", err) } mkPod := func(id string, rv string) *api.Pod { return &api.Pod{ObjectMeta: api.ObjectMeta{Name: id, ResourceVersion: rv}} } table := []struct { Pod *api.Pod exists bool }{ {mkPod("foo", ""), false}, {mkPod("rejected", ""), false}, {mkPod("bar", "55"), true}, {mkPod("baz", "32"), true}, } for _, item := range table { obj, exists, _ := s.Get(item.Pod) if e, a := item.exists, exists; e != a { t.Errorf("%v: expected %v, got %v", item.Pod, e, a) } if !exists { continue } if e, a := item.Pod.ResourceVersion, obj.(*api.Pod).ResourceVersion; e != a { t.Errorf("%v: expected %v, got %v", item.Pod, e, a) } } // RV should send the last version we see. if e, a := "32", resumeRV; e != a { t.Errorf("expected %v, got %v", e, a) } // last sync resource version should be the last version synced with store if e, a := "32", g.LastSyncResourceVersion(); e != a { t.Errorf("expected %v, got %v", e, a) } }
func TestReflectorStopWatch(t *testing.T) { s := NewStore(MetaNamespaceKeyFunc) g := NewReflector(&testLW{}, &api.Pod{}, s, 0) fw := watch.NewFake() var resumeRV string stopWatch := make(chan struct{}, 1) stopWatch <- struct{}{} err := g.watchHandler(fw, &resumeRV, neverExitWatch, stopWatch) if err != errorStopRequested { t.Errorf("expected stop error, got %q", err) } }
func TestReflectorWatchHandlerTimeout(t *testing.T) { s := NewStore(MetaNamespaceKeyFunc) g := NewReflector(&testLW{}, &api.Pod{}, s, 0) fw := watch.NewFake() var resumeRV string exit := make(chan time.Time, 1) exit <- time.Now() err := g.watchHandler(fw, &resumeRV, exit, util.NeverStop) if err != errorResyncRequested { t.Errorf("expected timeout error, but got %q", err) } }
func TestWatchHTTPTimeout(t *testing.T) { watcher := watch.NewFake() timeoutCh := make(chan time.Time) done := make(chan struct{}) // Setup a new watchserver watchServer := &WatchServer{ watcher, newCodec, func(obj runtime.Object) {}, &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 = "/api/" + newVersion + "/simple" dest.RawQuery = "watch=true" req, _ := http.NewRequest("GET", dest.String(), nil) client := http.Client{} resp, err := client.Do(req) watcher.Add(&Simple{TypeMeta: unversioned.TypeMeta{APIVersion: newVersion}}) // 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(100 * time.Millisecond): t.Errorf("Failed to stop watcher after 100ms of timeout signal") } // 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 TestUpdatePods(t *testing.T) { fakeWatch := watch.NewFake() client := &testclient.Fake{} client.AddWatchReactor("*", testclient.DefaultWatchReactor(fakeWatch, nil)) manager := NewReplicationManager(client, BurstReplicas) manager.podStoreSynced = alwaysReady received := make(chan string) manager.syncHandler = func(key string) error { obj, exists, err := manager.rcStore.Store.GetByKey(key) if !exists || err != nil { t.Errorf("Expected to find controller under key %v", key) } received <- obj.(*api.ReplicationController).Name return nil } stopCh := make(chan struct{}) defer close(stopCh) go util.Until(manager.worker, 10*time.Millisecond, stopCh) // Put 2 rcs and one pod into the controller's stores testControllerSpec1 := newReplicationController(1) manager.rcStore.Store.Add(testControllerSpec1) testControllerSpec2 := *testControllerSpec1 testControllerSpec2.Spec.Selector = map[string]string{"bar": "foo"} testControllerSpec2.Name = "barfoo" manager.rcStore.Store.Add(&testControllerSpec2) // Put one pod in the podStore pod1 := newPodList(manager.podStore.Store, 1, api.PodRunning, testControllerSpec1).Items[0] pod2 := pod1 pod2.Labels = testControllerSpec2.Spec.Selector // Send an update of the same pod with modified labels, and confirm we get a sync request for // both controllers manager.updatePod(&pod1, &pod2) expected := sets.NewString(testControllerSpec1.Name, testControllerSpec2.Name) for _, name := range expected.List() { t.Logf("Expecting update for %+v", name) select { case got := <-received: if !expected.Has(got) { t.Errorf("Expected keys %#v got %v", expected, got) } case <-time.After(util.ForeverTestTimeout): t.Errorf("Expected update notifications for controllers within 100ms each") } } }
func TestMutationDetector(t *testing.T) { source := NewFakeControllerSource() fakeWatch := watch.NewFake() lw := &testLW{ WatchFunc: func(options api.ListOptions) (watch.Interface, error) { return fakeWatch, nil }, ListFunc: func(options api.ListOptions) (runtime.Object, error) { return source.List(options) }, } pod := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "anything", Labels: map[string]string{"check": "foo"}, }, } stopCh := make(chan struct{}) defer close(stopCh) addReceived := make(chan bool) mutationFound := make(chan bool) informer := NewSharedInformer(lw, &api.Pod{}, 1*time.Second).(*sharedIndexInformer) informer.cacheMutationDetector = &defaultCacheMutationDetector{ name: "name", period: 1 * time.Second, failureFunc: func(message string) { mutationFound <- true }, } informer.AddEventHandler( ResourceEventHandlerFuncs{ AddFunc: func(obj interface{}) { addReceived <- true }, }, ) go informer.Run(stopCh) fakeWatch.Add(pod) select { case <-addReceived: } pod.Labels["change"] = "true" select { case <-mutationFound: } }
func TestReflectorWatchHandlerError(t *testing.T) { s := NewStore(MetaNamespaceKeyFunc) g := NewReflector(&testLW{}, &api.Pod{}, s, 0) fw := watch.NewFake() go func() { fw.Stop() }() var resumeRV string err := g.watchHandler(fw, &resumeRV, neverExitWatch, util.NeverStop) if err == nil { t.Errorf("unexpected non-error") } }
func TestHookExecutor_executeExecNewPodFailed(t *testing.T) { hook := &deployapi.LifecycleHook{ FailurePolicy: deployapi.LifecycleHookFailurePolicyAbort, ExecNewPod: &deployapi.ExecNewPodHook{ ContainerName: "container1", }, } config := deploytest.OkDeploymentConfig(1) deployment, _ := deployutil.MakeDeployment(config, kapi.Codecs.LegacyCodec(deployv1.SchemeGroupVersion)) client := newTestClient(config) podCreated := make(chan struct{}) var createdPod *kapi.Pod client.AddReactor("create", "pods", func(a testclient.Action) (handled bool, ret runtime.Object, err error) { defer close(podCreated) action := a.(testclient.CreateAction) object := action.GetObject() createdPod = object.(*kapi.Pod) return true, createdPod, nil }) podsWatch := watch.NewFake() client.AddWatchReactor("pods", testclient.DefaultWatchReactor(podsWatch, nil)) go func() { <-podCreated podsWatch.Add(createdPod) podCopy, _ := kapi.Scheme.Copy(createdPod) updatedPod := podCopy.(*kapi.Pod) updatedPod.Status.Phase = kapi.PodFailed podsWatch.Modify(updatedPod) }() executor := &HookExecutor{ pods: client, out: ioutil.Discard, decoder: kapi.Codecs.UniversalDecoder(), getPodLogs: func(*kapi.Pod) (io.ReadCloser, error) { return ioutil.NopCloser(strings.NewReader("test")), nil }, } err := executor.executeExecNewPod(hook, deployment, "hook", "test") if err == nil { t.Fatalf("expected an error, got none") } t.Logf("got expected error: %T", err) }
func TestWatchPods(t *testing.T) { testJob := newJob(2, 2) clientset := fake.NewSimpleClientset(testJob) fakeWatch := watch.NewFake() clientset.PrependWatchReactor("pods", core.DefaultWatchReactor(fakeWatch, nil)) manager := NewJobControllerFromClient(clientset, controller.NoResyncPeriodFunc) manager.podStoreSynced = alwaysReady // Put one job and one pod into the store manager.jobStore.Store.Add(testJob) received := make(chan struct{}) // The pod update sent through the fakeWatcher should figure out the managing job and // send it into the syncHandler. manager.syncHandler = func(key string) error { obj, exists, err := manager.jobStore.Store.GetByKey(key) if !exists || err != nil { t.Errorf("Expected to find job under key %v", key) close(received) return nil } job, ok := obj.(*batch.Job) if !ok { t.Errorf("unexpected type: %v %#v", reflect.TypeOf(obj), obj) close(received) return nil } if !api.Semantic.DeepDerivative(job, testJob) { t.Errorf("\nExpected %#v,\nbut got %#v", testJob, job) close(received) return nil } close(received) return nil } // Start only the pod watcher and the workqueue, send a watch event, // and make sure it hits the sync method for the right job. stopCh := make(chan struct{}) defer close(stopCh) go manager.internalPodInformer.Run(stopCh) go wait.Until(manager.worker, 10*time.Millisecond, stopCh) pods := newPodList(1, api.PodRunning, testJob) testPod := pods[0] testPod.Status.Phase = api.PodFailed fakeWatch.Add(&testPod) t.Log("Waiting for pod to reach syncHandler") <-received }
func NewMockPodsListWatch(initialPodList api.PodList) *MockPodsListWatch { lw := MockPodsListWatch{ fakeWatcher: watch.NewFake(), list: initialPodList, } lw.ListWatch = cache.ListWatch{ WatchFunc: func(resourceVersion string) (watch.Interface, error) { return lw.fakeWatcher, nil }, ListFunc: func() (runtime.Object, error) { return &lw.list, nil }, } return &lw }
// NewSimpleFake returns a client that will respond with the provided objects func NewSimpleFake(objects ...runtime.Object) *Fake { o := NewObjects(api.Scheme, api.Scheme) for _, obj := range objects { if err := o.Add(obj); err != nil { panic(err) } } fakeClient := &Fake{} fakeClient.AddReactor("*", "*", ObjectReaction(o, api.RESTMapper)) fakeClient.AddWatchReactor("*", DefaultWatchReactor(watch.NewFake(), nil)) return fakeClient }
// NewSimpleFake returns a client that will respond with the provided objects func NewSimpleFake(objects ...runtime.Object) *Fake { o := core.NewObjectTracker(kapi.Scheme, kapi.Codecs.UniversalDecoder()) for _, obj := range objects { if err := o.Add(obj); err != nil { panic(err) } } fakeClient := &Fake{} fakeClient.AddReactor("*", "*", core.ObjectReaction(o, registered.RESTMapper())) fakeClient.AddWatchReactor("*", core.DefaultWatchReactor(watch.NewFake(), nil)) return fakeClient }
// Clientset returns a clientset that will respond with the provided objects func NewSimpleClientset(objects ...runtime.Object) *Clientset { o := core.NewObjects(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, api.RESTMapper)) fakePtr.AddWatchReactor("*", core.DefaultWatchReactor(watch.NewFake(), nil)) return &Clientset{fakePtr} }
func TestWatchPods(t *testing.T) { fakeWatch := watch.NewFake() client := &fake.Clientset{} client.AddWatchReactor("*", core.DefaultWatchReactor(fakeWatch, nil)) manager := NewReplicaSetControllerFromClient(client, controller.NoResyncPeriodFunc, BurstReplicas, 0) manager.podStoreSynced = alwaysReady // Put one ReplicaSet and one pod into the controller's stores labelMap := map[string]string{"foo": "bar"} testRSSpec := newReplicaSet(1, labelMap) manager.rsStore.Store.Add(testRSSpec) received := make(chan string) // The pod update sent through the fakeWatcher should figure out the managing ReplicaSet and // send it into the syncHandler. manager.syncHandler = func(key string) error { obj, exists, err := manager.rsStore.Store.GetByKey(key) if !exists || err != nil { t.Errorf("Expected to find replica set under key %v", key) } rsSpec := obj.(*extensions.ReplicaSet) if !api.Semantic.DeepDerivative(rsSpec, testRSSpec) { t.Errorf("\nExpected %#v,\nbut got %#v", testRSSpec, rsSpec) } close(received) return nil } // Start only the pod watcher and the workqueue, send a watch event, // and make sure it hits the sync method for the right ReplicaSet. stopCh := make(chan struct{}) defer close(stopCh) go manager.podController.Run(stopCh) go manager.internalPodInformer.Run(stopCh) go wait.Until(manager.worker, 10*time.Millisecond, stopCh) pods := newPodList(nil, 1, api.PodRunning, labelMap, testRSSpec, "pod") testPod := pods.Items[0] testPod.Status.Phase = api.PodFailed fakeWatch.Add(&testPod) select { case <-received: case <-time.After(wait.ForeverTestTimeout): t.Errorf("unexpected timeout from result channel") } }
func TestWatchPods(t *testing.T) { testJob := newJob(2, 2) clientset := fake.NewSimpleClientset(testJob) fakeWatch := watch.NewFake() clientset.PrependWatchReactor("pods", core.DefaultWatchReactor(fakeWatch, nil)) manager, sharedInformerFactory := newJobControllerFromClient(clientset, controller.NoResyncPeriodFunc) manager.podStoreSynced = alwaysReady manager.jobStoreSynced = alwaysReady // Put one job and one pod into the store sharedInformerFactory.Jobs().Informer().GetIndexer().Add(testJob) received := make(chan struct{}) // The pod update sent through the fakeWatcher should figure out the managing job and // send it into the syncHandler. manager.syncHandler = func(key string) error { ns, name, err := cache.SplitMetaNamespaceKey(key) if err != nil { t.Errorf("Error getting namespace/name from key %v: %v", key, err) } job, err := manager.jobLister.Jobs(ns).Get(name) if err != nil { t.Errorf("Expected to find job under key %v: %v", key, err) } if !api.Semantic.DeepDerivative(job, testJob) { t.Errorf("\nExpected %#v,\nbut got %#v", testJob, job) close(received) return nil } close(received) return nil } // Start only the pod watcher and the workqueue, send a watch event, // and make sure it hits the sync method for the right job. stopCh := make(chan struct{}) defer close(stopCh) go sharedInformerFactory.Pods().Informer().Run(stopCh) go wait.Until(manager.worker, 10*time.Millisecond, stopCh) pods := newPodList(1, api.PodRunning, testJob) testPod := pods[0] testPod.Status.Phase = api.PodFailed fakeWatch.Add(&testPod) t.Log("Waiting for pod to reach syncHandler") <-received }
func TestWatchPods(t *testing.T) { fakeWatch := watch.NewFake() client := &testclient.Fake{} client.AddWatchReactor("*", testclient.DefaultWatchReactor(fakeWatch, nil)) manager := NewJobController(client, controller.NoResyncPeriodFunc) manager.podStoreSynced = alwaysReady // Put one job and one pod into the store testJob := newJob(2, 2) manager.jobStore.Store.Add(testJob) received := make(chan string) // The pod update sent through the fakeWatcher should figure out the managing job and // send it into the syncHandler. manager.syncHandler = func(key string) error { obj, exists, err := manager.jobStore.Store.GetByKey(key) if !exists || err != nil { t.Errorf("Expected to find job under key %v", key) } job := obj.(*extensions.Job) if !api.Semantic.DeepDerivative(job, testJob) { t.Errorf("\nExpected %#v,\nbut got %#v", testJob, job) } close(received) return nil } // Start only the pod watcher and the workqueue, send a watch event, // and make sure it hits the sync method for the right job. stopCh := make(chan struct{}) defer close(stopCh) go manager.podController.Run(stopCh) go util.Until(manager.worker, 10*time.Millisecond, stopCh) pods := newPodList(1, api.PodRunning, testJob) testPod := pods[0] testPod.Status.Phase = api.PodFailed fakeWatch.Add(&testPod) select { case <-received: case <-time.After(controllerTimeout): t.Errorf("Expected 1 call but got 0") } }
func TestWatchPods(t *testing.T) { fakeWatch := watch.NewFake() c := &fake.Clientset{} c.AddWatchReactor("*", core.DefaultWatchReactor(fakeWatch, nil)) manager := NewReplicationManager(c, controller.NoResyncPeriodFunc, BurstReplicas) manager.podStoreSynced = alwaysReady // Put one rc and one pod into the controller's stores testControllerSpec := newReplicationController(1) manager.rcStore.Store.Add(testControllerSpec) received := make(chan string) // The pod update sent through the fakeWatcher should figure out the managing rc and // send it into the syncHandler. manager.syncHandler = func(key string) error { obj, exists, err := manager.rcStore.Store.GetByKey(key) if !exists || err != nil { t.Errorf("Expected to find controller under key %v", key) } controllerSpec := obj.(*api.ReplicationController) if !api.Semantic.DeepDerivative(controllerSpec, testControllerSpec) { t.Errorf("\nExpected %#v,\nbut got %#v", testControllerSpec, controllerSpec) } close(received) return nil } // Start only the pod watcher and the workqueue, send a watch event, // and make sure it hits the sync method for the right rc. stopCh := make(chan struct{}) defer close(stopCh) go manager.podController.Run(stopCh) go wait.Until(manager.worker, 10*time.Millisecond, stopCh) pods := newPodList(nil, 1, api.PodRunning, testControllerSpec) testPod := pods.Items[0] testPod.Status.Phase = api.PodFailed fakeWatch.Add(&testPod) select { case <-received: case <-time.After(wait.ForeverTestTimeout): t.Errorf("Expected 1 call but got 0") } }
func TestWatchJobs(t *testing.T) { clientset := fake.NewSimpleClientset() fakeWatch := watch.NewFake() clientset.PrependWatchReactor("jobs", core.DefaultWatchReactor(fakeWatch, nil)) manager, sharedInformerFactory := newJobControllerFromClient(clientset, controller.NoResyncPeriodFunc) manager.podStoreSynced = alwaysReady manager.jobStoreSynced = alwaysReady var testJob batch.Job received := make(chan struct{}) // The update sent through the fakeWatcher should make its way into the workqueue, // and eventually into the syncHandler. manager.syncHandler = func(key string) error { defer close(received) ns, name, err := cache.SplitMetaNamespaceKey(key) if err != nil { t.Errorf("Error getting namespace/name from key %v: %v", key, err) } job, err := manager.jobLister.Jobs(ns).Get(name) if err != nil || job == nil { t.Errorf("Expected to find job under key %v: %v", key, err) return nil } if !api.Semantic.DeepDerivative(*job, testJob) { t.Errorf("Expected %#v, but got %#v", testJob, *job) } return nil } // Start only the job watcher and the workqueue, send a watch event, // and make sure it hits the sync method. stopCh := make(chan struct{}) defer close(stopCh) sharedInformerFactory.Start(stopCh) go manager.Run(1, stopCh) // We're sending new job to see if it reaches syncHandler. testJob.Namespace = "bar" testJob.Name = "foo" fakeWatch.Add(&testJob) t.Log("Waiting for job to reach syncHandler") <-received }
func NewMockPodsListWatch(initialPodList api.PodList) *MockPodsListWatch { lw := MockPodsListWatch{ fakeWatcher: watch.NewFake(), list: initialPodList, } lw.ListWatch = cache.ListWatch{ WatchFunc: func(resourceVersion string) (watch.Interface, error) { return lw.fakeWatcher, nil }, ListFunc: func() (runtime.Object, error) { lw.lock.Lock() defer lw.lock.Unlock() listCopy, err := api.Scheme.DeepCopy(&lw.list) return listCopy.(*api.PodList), err }, } return &lw }
func TestDecoratedWatcherError(t *testing.T) { w := watch.NewFake() expErr := fmt.Errorf("expected error") decorator := func(obj runtime.Object) error { return expErr } dw := newDecoratedWatcher(w, decorator) defer dw.Stop() go w.Add(&api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}) select { case e := <-dw.ResultChan(): if e.Type != watch.Error { t.Errorf("event type want=%v, get=%v", watch.Error, e.Type) } case <-time.After(wait.ForeverTestTimeout): t.Errorf("timeout after %v", wait.ForeverTestTimeout) } }