func TestGetEtcd(t *testing.T) { fakeClient := tools.MakeFakeEtcdClient(t) ch := make(chan interface{}, 1) manifest := api.ContainerManifest{ID: "foo", Version: "v1beta1", Containers: []api.Container{{Name: "1", Image: "foo"}}} fakeClient.Data["/registry/hosts/machine/kubelet"] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: &etcd.Node{ Value: api.EncodeOrDie(&api.ContainerManifestList{ Items: []api.ContainerManifest{manifest}, }), ModifiedIndex: 1, }, }, E: nil, } c := SourceEtcd{"/registry/hosts/machine/kubelet", fakeClient, ch, time.Millisecond} lastIndex, err := c.fetchNextState(0) if err != nil { t.Errorf("Unexpected error: %v", err) } if lastIndex != 2 { t.Errorf("Expected %#v, Got %#v", 2, lastIndex) } update := (<-ch).(kubelet.PodUpdate) expected := CreatePodUpdate(kubelet.SET, kubelet.Pod{Name: "foo", Manifest: manifest}) if !reflect.DeepEqual(expected, update) { t.Errorf("Expected %#v, Got %#v", expected, update) } for i := range update.Pods { if errs := kubelet.ValidatePod(&update.Pods[i]); len(errs) != 0 { t.Errorf("Expected no validation errors on %#v, Got %#v", update.Pods[i], errs) } } }
func TestEtcdUpdateEndpoints(t *testing.T) { fakeClient := tools.MakeFakeEtcdClient(t) fakeClient.TestIndex = true registry := MakeTestEtcdRegistry(fakeClient, []string{"machine"}) endpoints := api.Endpoints{ JSONBase: api.JSONBase{ID: "foo"}, Endpoints: []string{"baz", "bar"}, } fakeClient.Set("/registry/services/endpoints/foo", util.MakeJSONString(api.Endpoints{}), 0) err := registry.UpdateEndpoints(endpoints) if err != nil { t.Errorf("unexpected error: %v", err) } response, err := fakeClient.Get("/registry/services/endpoints/foo", false, false) if err != nil { t.Fatalf("Unexpected error %v", err) } var endpointsOut api.Endpoints err = api.DecodeInto([]byte(response.Node.Value), &endpointsOut) if !reflect.DeepEqual(endpoints, endpointsOut) { t.Errorf("Unexpected endpoints: %#v, expected %#v", endpointsOut, endpoints) } }
func TestWatchControllers(t *testing.T) { fakeEtcd := tools.MakeFakeEtcdClient(t) fakeWatcher := watch.NewFake() manager := MakeReplicationManager(fakeEtcd, nil) manager.watchMaker = func() (watch.Interface, error) { return fakeWatcher, nil } var testControllerSpec api.ReplicationController received := make(chan struct{}) manager.syncHandler = func(controllerSpec api.ReplicationController) error { if !reflect.DeepEqual(controllerSpec, testControllerSpec) { t.Errorf("Expected %#v, but got %#v", testControllerSpec, controllerSpec) } close(received) return nil } go manager.watchControllers() // Test normal case testControllerSpec.ID = "foo" fakeWatcher.Add(&testControllerSpec) select { case <-received: case <-time.After(10 * time.Millisecond): t.Errorf("Expected 1 call but got 0") } }
func TestEtcdDeletePodMultipleContainers(t *testing.T) { fakeClient := tools.MakeFakeEtcdClient(t) key := "/registry/hosts/machine/pods/foo" fakeClient.Set(key, util.MakeJSONString(api.Pod{JSONBase: api.JSONBase{ID: "foo"}}), 0) fakeClient.Set("/registry/hosts/machine/kubelet", util.MakeJSONString([]api.ContainerManifest{ {ID: "foo"}, {ID: "bar"}, }), 0) registry := MakeTestEtcdRegistry(fakeClient, []string{"machine"}) err := registry.DeletePod("foo") expectNoError(t, err) if len(fakeClient.DeletedKeys) != 1 { t.Errorf("Expected 1 delete, found %#v", fakeClient.DeletedKeys) } if fakeClient.DeletedKeys[0] != key { t.Errorf("Unexpected key: %s, expected %s", fakeClient.DeletedKeys[0], key) } response, _ := fakeClient.Get("/registry/hosts/machine/kubelet", false, false) var manifests []api.ContainerManifest json.Unmarshal([]byte(response.Node.Value), &manifests) if len(manifests) != 1 { t.Errorf("Unexpected manifest set: %#v, expected empty", manifests) } if manifests[0].ID != "bar" { t.Errorf("Deleted wrong manifest: %#v", manifests) } }
func TestGetEtcd(t *testing.T) { fakeClient := tools.MakeFakeEtcdClient(t) ch := make(chan interface{}, 1) fakeClient.Data["/registry/hosts/machine/kubelet"] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: &etcd.Node{ Value: api.EncodeOrDie(&api.ContainerManifestList{ Items: []api.ContainerManifest{{ID: "foo"}}, }), ModifiedIndex: 1, }, }, E: nil, } c := SourceEtcd{"/registry/hosts/machine/kubelet", fakeClient, ch, time.Millisecond} lastIndex, err := c.fetchNextState(0) if err != nil { t.Errorf("Unexpected error: %v", err) } if lastIndex != 2 { t.Errorf("Expected %#v, Got %#v", 2, lastIndex) } update := (<-ch).(kubelet.PodUpdate) expected := CreatePodUpdate(kubelet.SET, kubelet.Pod{Name: "foo", Manifest: api.ContainerManifest{ID: "foo"}}) if !reflect.DeepEqual(expected, update) { t.Errorf("Expected %#v, Got %#v", expected, update) } }
func TestEtcdListPods(t *testing.T) { fakeClient := tools.MakeFakeEtcdClient(t) key := "/registry/hosts/machine/pods" fakeClient.Data[key] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: &etcd.Node{ Nodes: []*etcd.Node{ { Value: util.MakeJSONString(api.Pod{JSONBase: api.JSONBase{ID: "foo"}}), }, { Value: util.MakeJSONString(api.Pod{JSONBase: api.JSONBase{ID: "bar"}}), }, }, }, }, E: nil, } registry := MakeTestEtcdRegistry(fakeClient, []string{"machine"}) pods, err := registry.ListPods(labels.Everything()) if err != nil { t.Errorf("unexpected error: %v", err) } if len(pods) != 2 || pods[0].ID != "foo" || pods[1].ID != "bar" { t.Errorf("Unexpected pod list: %#v", pods) } if pods[0].CurrentState.Host != "machine" || pods[1].CurrentState.Host != "machine" { t.Errorf("Failed to populate host name.") } }
func TestEtcdListControllers(t *testing.T) { fakeClient := tools.MakeFakeEtcdClient(t) key := "/registry/controllers" fakeClient.Data[key] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: &etcd.Node{ Nodes: []*etcd.Node{ { Value: util.MakeJSONString(api.ReplicationController{JSONBase: api.JSONBase{ID: "foo"}}), }, { Value: util.MakeJSONString(api.ReplicationController{JSONBase: api.JSONBase{ID: "bar"}}), }, }, }, }, E: nil, } registry := MakeTestEtcdRegistry(fakeClient, []string{"machine"}) controllers, err := registry.ListControllers() if err != nil { t.Errorf("unexpected error: %v", err) } if len(controllers) != 2 || controllers[0].ID != "foo" || controllers[1].ID != "bar" { t.Errorf("Unexpected controller list: %#v", controllers) } }
func TestEtcdCreateController(t *testing.T) { fakeClient := tools.MakeFakeEtcdClient(t) registry := MakeTestEtcdRegistry(fakeClient, []string{"machine"}) err := registry.CreateController(api.ReplicationController{ JSONBase: api.JSONBase{ ID: "foo", }, }) if err != nil { t.Errorf("unexpected error: %v", err) } resp, err := fakeClient.Get("/registry/controllers/foo", false, false) if err != nil { t.Fatalf("Unexpected error %v", err) } var ctrl api.ReplicationController err = api.DecodeInto([]byte(resp.Node.Value), &ctrl) if err != nil { t.Errorf("unexpected error: %v", err) } if ctrl.ID != "foo" { t.Errorf("Unexpected pod: %#v %s", ctrl, resp.Node.Value) } }
func TestEtcdListServices(t *testing.T) { fakeClient := tools.MakeFakeEtcdClient(t) key := "/registry/services/specs" fakeClient.Data[key] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: &etcd.Node{ Nodes: []*etcd.Node{ { Value: util.MakeJSONString(api.Service{JSONBase: api.JSONBase{ID: "foo"}}), }, { Value: util.MakeJSONString(api.Service{JSONBase: api.JSONBase{ID: "bar"}}), }, }, }, }, E: nil, } registry := MakeTestEtcdRegistry(fakeClient, []string{"machine"}) services, err := registry.ListServices() if err != nil { t.Errorf("unexpected error: %v", err) } if len(services.Items) != 2 || services.Items[0].ID != "foo" || services.Items[1].ID != "bar" { t.Errorf("Unexpected pod list: %#v", services) } }
func TestEtcdCreateService(t *testing.T) { fakeClient := tools.MakeFakeEtcdClient(t) fakeClient.Data["/registry/services/specs/foo"] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: nil, }, E: tools.EtcdErrorNotFound, } registry := MakeTestEtcdRegistry(fakeClient, []string{"machine"}) err := registry.CreateService(api.Service{ JSONBase: api.JSONBase{ID: "foo"}, }) if err != nil { t.Errorf("unexpected error: %v", err) } resp, err := fakeClient.Get("/registry/services/specs/foo", false, false) if err != nil { t.Errorf("unexpected error: %v", err) } var service api.Service err = api.DecodeInto([]byte(resp.Node.Value), &service) if err != nil { t.Errorf("unexpected error: %v", err) } if service.ID != "foo" { t.Errorf("Unexpected service: %#v %s", service, resp.Node.Value) } }
func TestEtcdCreatePodWithContainersError(t *testing.T) { fakeClient := tools.MakeFakeEtcdClient(t) fakeClient.Data["/registry/hosts/machine/pods/foo"] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: nil, }, E: tools.EtcdErrorNotFound, } fakeClient.Data["/registry/hosts/machine/kubelet"] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: nil, }, E: tools.EtcdErrorValueRequired, } registry := MakeTestEtcdRegistry(fakeClient, []string{"machine"}) err := registry.CreatePod("machine", api.Pod{ JSONBase: api.JSONBase{ ID: "foo", }, }) if err == nil { t.Error("Unexpected non-error") } _, err = fakeClient.Get("/registry/hosts/machine/pods/foo", false, false) if err == nil { t.Error("Unexpected non-error") } if !tools.IsEtcdNotFound(err) { t.Errorf("Unexpected error: %#v", err) } }
func TestEtcdUpdateService(t *testing.T) { fakeClient := tools.MakeFakeEtcdClient(t) fakeClient.TestIndex = true resp, _ := fakeClient.Set("/registry/services/specs/foo", util.MakeJSONString(api.Service{JSONBase: api.JSONBase{ID: "foo"}}), 0) registry := MakeTestEtcdRegistry(fakeClient, []string{"machine"}) testService := api.Service{ JSONBase: api.JSONBase{ID: "foo", ResourceVersion: resp.Node.ModifiedIndex}, Labels: map[string]string{ "baz": "bar", }, Selector: map[string]string{ "baz": "bar", }, } err := registry.UpdateService(testService) if err != nil { t.Errorf("unexpected error: %v", err) } svc, err := registry.GetService("foo") if err != nil { t.Errorf("unexpected error: %v", err) } // Clear modified indices before the equality test. svc.ResourceVersion = 0 testService.ResourceVersion = 0 if !reflect.DeepEqual(*svc, testService) { t.Errorf("Unexpected service: got\n %#v\n, wanted\n %#v", svc, testService) } }
func TestWatchEtcd(t *testing.T) { fakeClient := tools.MakeFakeEtcdClient(t) ch := make(chan interface{}, 1) fakeClient.Data["/registry/hosts/machine/kubelet"] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: &etcd.Node{ Value: util.MakeJSONString([]api.Container{}), ModifiedIndex: 2, }, }, E: nil, } c := SourceEtcd{"/registry/hosts/machine/kubelet", fakeClient, ch, time.Millisecond} lastIndex, err := c.fetchNextState(1) if err != nil { t.Errorf("Unexpected error: %v", err) } if lastIndex != 3 { t.Errorf("Expected %d, Got %d", 3, lastIndex) } update := (<-ch).(kubelet.PodUpdate) expected := CreatePodUpdate(kubelet.SET) if !reflect.DeepEqual(expected, update) { t.Errorf("Expected %#v, Got %#v", expected, update) } }
func TestGetEtcdData(t *testing.T) { fakeClient := tools.MakeFakeEtcdClient(t) ch := make(chan interface{}) fakeClient.Data["/registry/hosts/machine/kubelet"] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: &etcd.Node{ Value: api.EncodeOrDie(&api.ContainerManifestList{ Items: []api.ContainerManifest{{ID: "foo"}}, }), ModifiedIndex: 1, }, }, E: nil, } NewSourceEtcd("/registry/hosts/machine/kubelet", fakeClient, time.Millisecond, ch) //TODO: update FakeEtcdClient.Watch to handle receiver=nil with a given index //returns an infinite stream of updates for i := 0; i < 2; i++ { update := (<-ch).(kubelet.PodUpdate) expected := CreatePodUpdate(kubelet.SET, kubelet.Pod{Name: "foo", Manifest: api.ContainerManifest{ID: "foo"}}) if !reflect.DeepEqual(expected, update) { t.Errorf("Expected %#v, Got %#v", expected, update) } } }
func TestEtcdDeletePod(t *testing.T) { fakeClient := tools.MakeFakeEtcdClient(t) fakeClient.TestIndex = true key := "/registry/hosts/machine/pods/foo" fakeClient.Set(key, util.MakeJSONString(api.Pod{JSONBase: api.JSONBase{ID: "foo"}}), 0) fakeClient.Set("/registry/hosts/machine/kubelet", api.EncodeOrDie(&api.ContainerManifestList{ Items: []api.ContainerManifest{ {ID: "foo"}, }, }), 0) registry := MakeTestEtcdRegistry(fakeClient, []string{"machine"}) err := registry.DeletePod("foo") if err != nil { t.Errorf("unexpected error: %v", err) } if len(fakeClient.DeletedKeys) != 1 { t.Errorf("Expected 1 delete, found %#v", fakeClient.DeletedKeys) } else if fakeClient.DeletedKeys[0] != key { t.Errorf("Unexpected key: %s, expected %s", fakeClient.DeletedKeys[0], key) } response, err := fakeClient.Get("/registry/hosts/machine/kubelet", false, false) if err != nil { t.Fatalf("Unexpected error %v", err) } var manifests api.ContainerManifestList api.DecodeInto([]byte(response.Node.Value), &manifests) if len(manifests.Items) != 0 { t.Errorf("Unexpected container set: %s, expected empty", response.Node.Value) } }
func TestEtcdCreatePodWithContainersNotFound(t *testing.T) { fakeClient := tools.MakeFakeEtcdClient(t) fakeClient.TestIndex = true fakeClient.Data["/registry/pods/foo"] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: nil, }, E: tools.EtcdErrorNotFound, } fakeClient.Data["/registry/hosts/machine/kubelet"] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: nil, }, E: tools.EtcdErrorNotFound, } registry := MakeTestEtcdRegistry(fakeClient, []string{"machine"}) err := registry.CreatePod("machine", api.Pod{ JSONBase: api.JSONBase{ ID: "foo", }, DesiredState: api.PodState{ Manifest: api.ContainerManifest{ ID: "foo", Containers: []api.Container{ { Name: "foo", }, }, }, }, }) if err != nil { t.Fatalf("unexpected error: %v", err) } resp, err := fakeClient.Get("/registry/pods/foo", false, false) if err != nil { t.Fatalf("Unexpected error %v", err) } var pod api.Pod err = api.DecodeInto([]byte(resp.Node.Value), &pod) if err != nil { t.Errorf("unexpected error: %v", err) } if pod.ID != "foo" { t.Errorf("Unexpected pod: %#v %s", pod, resp.Node.Value) } var manifests api.ContainerManifestList resp, err = fakeClient.Get("/registry/hosts/machine/kubelet", false, false) if err != nil { t.Errorf("unexpected error: %v", err) } err = api.DecodeInto([]byte(resp.Node.Value), &manifests) if len(manifests.Items) != 1 || manifests.Items[0].ID != "foo" { t.Errorf("Unexpected manifest list: %#v", manifests) } }
func TestEtcdGetService(t *testing.T) { fakeClient := tools.MakeFakeEtcdClient(t) fakeClient.Set("/registry/services/specs/foo", util.MakeJSONString(api.Service{JSONBase: api.JSONBase{ID: "foo"}}), 0) registry := MakeTestEtcdRegistry(fakeClient, []string{"machine"}) service, err := registry.GetService("foo") expectNoError(t, err) if service.ID != "foo" { t.Errorf("Unexpected pod: %#v", service) } }
func TestEtcdGetPod(t *testing.T) { fakeClient := tools.MakeFakeEtcdClient(t) fakeClient.Set("/registry/hosts/machine/pods/foo", util.MakeJSONString(api.Pod{JSONBase: api.JSONBase{ID: "foo"}}), 0) registry := MakeTestEtcdRegistry(fakeClient, []string{"machine"}) pod, err := registry.GetPod("foo") expectNoError(t, err) if pod.ID != "foo" { t.Errorf("Unexpected pod: %#v", pod) } }
func TestEtcdGetController(t *testing.T) { fakeClient := tools.MakeFakeEtcdClient(t) fakeClient.Set("/registry/controllers/foo", util.MakeJSONString(api.ReplicationController{JSONBase: api.JSONBase{ID: "foo"}}), 0) registry := MakeTestEtcdRegistry(fakeClient, []string{"machine"}) ctrl, err := registry.GetController("foo") expectNoError(t, err) if ctrl.ID != "foo" { t.Errorf("Unexpected controller: %#v", ctrl) } }
func TestEtcdCreateServiceAlreadyExisting(t *testing.T) { fakeClient := tools.MakeFakeEtcdClient(t) fakeClient.Set("/registry/services/specs/foo", api.EncodeOrDie(api.Service{JSONBase: api.JSONBase{ID: "foo"}}), 0) registry := MakeTestEtcdRegistry(fakeClient, []string{"machine"}) err := registry.CreateService(api.Service{ JSONBase: api.JSONBase{ID: "foo"}, }) if !apiserver.IsAlreadyExists(err) { t.Errorf("expected already exists err, got %#v", err) } }
func TestGetEtcdNoData(t *testing.T) { fakeClient := tools.MakeFakeEtcdClient(t) ch := make(chan interface{}, 1) fakeClient.Data["/registry/hosts/machine/kubelet"] = tools.EtcdResponseWithError{ R: &etcd.Response{}, E: nil, } c := SourceEtcd{"/registry/hosts/machine/kubelet", fakeClient, ch, time.Millisecond} _, err := c.fetchNextState(0) expectError(t, err) expectEmptyChannel(t, ch) }
func makeTestKubelet(t *testing.T) (*Kubelet, *tools.FakeEtcdClient, *FakeDockerClient) { fakeEtcdClient := tools.MakeFakeEtcdClient(t) fakeDocker := &FakeDockerClient{ err: nil, } kubelet := New() kubelet.DockerClient = fakeDocker kubelet.DockerPuller = &FakeDockerPuller{} kubelet.EtcdClient = fakeEtcdClient return kubelet, fakeEtcdClient, fakeDocker }
func TestEtcdMasterOther(t *testing.T) { path := "foo" etcd := tools.MakeFakeEtcdClient(t) etcd.Set(path, "baz", 0) master := NewEtcdMasterElector(etcd) w := master.Elect(path, "bar") result := <-w.ResultChan() if result.Type != watch.Modified || result.Object.(string) != "baz" { t.Errorf("unexpected event: %#v", result) } w.Stop() }
func TestEtcdGetPod(t *testing.T) { fakeClient := tools.MakeFakeEtcdClient(t) fakeClient.Set("/registry/pods/foo", api.EncodeOrDie(api.Pod{JSONBase: api.JSONBase{ID: "foo"}}), 0) registry := MakeTestEtcdRegistry(fakeClient, []string{"machine"}) pod, err := registry.GetPod("foo") if err != nil { t.Errorf("unexpected error: %v", err) } if pod.ID != "foo" { t.Errorf("Unexpected pod: %#v", pod) } }
func TestEtcdGetController(t *testing.T) { fakeClient := tools.MakeFakeEtcdClient(t) fakeClient.Set("/registry/controllers/foo", api.EncodeOrDie(api.ReplicationController{JSONBase: api.JSONBase{ID: "foo"}}), 0) registry := MakeTestEtcdRegistry(fakeClient, []string{"machine"}) ctrl, err := registry.GetController("foo") if err != nil { t.Errorf("unexpected error: %v", err) } if ctrl.ID != "foo" { t.Errorf("Unexpected controller: %#v", ctrl) } }
func TestEtcdGetService(t *testing.T) { fakeClient := tools.MakeFakeEtcdClient(t) fakeClient.Set("/registry/services/specs/foo", api.EncodeOrDie(api.Service{JSONBase: api.JSONBase{ID: "foo"}}), 0) registry := MakeTestEtcdRegistry(fakeClient, []string{"machine"}) service, err := registry.GetService("foo") if err != nil { t.Errorf("unexpected error: %v", err) } if service.ID != "foo" { t.Errorf("Unexpected pod: %#v", service) } }
func TestEtcdDeleteController(t *testing.T) { fakeClient := tools.MakeFakeEtcdClient(t) registry := MakeTestEtcdRegistry(fakeClient, []string{"machine"}) err := registry.DeleteController("foo") expectNoError(t, err) if len(fakeClient.DeletedKeys) != 1 { t.Errorf("Expected 1 delete, found %#v", fakeClient.DeletedKeys) } key := "/registry/controllers/foo" if fakeClient.DeletedKeys[0] != key { t.Errorf("Unexpected key: %s, expected %s", fakeClient.DeletedKeys[0], key) } }
func TestWatchControllers(t *testing.T) { defer beginTimeout(20 * time.Second).done() fakeEtcd := tools.MakeFakeEtcdClient(t) manager := MakeReplicationManager(fakeEtcd, nil) var testControllerSpec api.ReplicationController received := make(chan bool) manager.syncHandler = func(controllerSpec api.ReplicationController) error { if !reflect.DeepEqual(controllerSpec, testControllerSpec) { t.Errorf("Expected %#v, but got %#v", testControllerSpec, controllerSpec) } close(received) return nil } go manager.watchControllers() fakeEtcd.WaitForWatchCompletion() // Test normal case testControllerSpec.ID = "foo" fakeEtcd.WatchResponse <- &etcd.Response{ Action: "set", Node: &etcd.Node{ Value: util.MakeJSONString(testControllerSpec), }, } select { case <-received: case <-time.After(10 * time.Millisecond): t.Errorf("Expected 1 call but got 0") } // Test error case fakeEtcd.WatchInjectError <- fmt.Errorf("Injected error") // Did everything shut down? if _, open := <-fakeEtcd.WatchResponse; open { t.Errorf("An injected error did not cause a graceful shutdown") } // Test purposeful shutdown go manager.watchControllers() fakeEtcd.WaitForWatchCompletion() fakeEtcd.WatchStop <- true // Did everything shut down? if _, open := <-fakeEtcd.WatchResponse; open { t.Errorf("A stop did not cause a graceful shutdown") } }
func makeTestKubelet(t *testing.T) (*Kubelet, *tools.FakeEtcdClient, *FakeDockerClient) { fakeEtcdClient := tools.MakeFakeEtcdClient(t) fakeDocker := &FakeDockerClient{ err: nil, } kubelet := &Kubelet{} kubelet.dockerClient = fakeDocker kubelet.dockerPuller = &FakeDockerPuller{} kubelet.etcdClient = fakeEtcdClient kubelet.rootDirectory = "/tmp/kubelet" kubelet.podWorkers = newPodWorkers() return kubelet, fakeEtcdClient, fakeDocker }
func TestEtcdGetServiceNotFound(t *testing.T) { fakeClient := tools.MakeFakeEtcdClient(t) fakeClient.Data["/registry/services/specs/foo"] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: nil, }, E: tools.EtcdErrorNotFound, } registry := MakeTestEtcdRegistry(fakeClient, []string{"machine"}) _, err := registry.GetService("foo") if err == nil { t.Errorf("Unexpected non-error.") } }