func setup(t etcdrunner.TestingT, ec EtcdClient, dc discoverdClient) (discoverdClient, EtcdClient, func()) { if *fake { if ec == nil { ec = newFakeEtcd() } if dc == nil { dc = newFakeDiscoverd() } return dc, ec, nil } var killEtcd, killDiscoverd func() if ec == nil { killEtcd = etcdrunner.RunEtcdServer(t) ec = etcd.NewClient(nil) } if dc == nil { dc, killDiscoverd = testutil.BootDiscoverd(t, "") } return dc, ec, func() { if killDiscoverd != nil { dc.Close() killDiscoverd() } if killEtcd != nil { killEtcd() } } }
func setup(t etcdrunner.TestingT, ec EtcdClient, dc discoverdClient) (discoverdClient, EtcdClient, func()) { if *fake { if ec == nil { ec = newFakeEtcd() } if dc == nil { dc = newFakeDiscoverd() } return dc, ec, nil } var killEtcd, killDiscoverd func() var etcdAddr string if ec == nil { etcdAddr, killEtcd = etcdrunner.RunEtcdServer(t) ec = etcd.NewClient([]string{etcdAddr}) } else if c, ok := ec.(*etcd.Client); ok { etcdAddr = c.GetCluster()[0] } if dc == nil { dc, killDiscoverd = testutil.BootDiscoverd(t, "", etcdAddr) } return dc, ec, func() { if killDiscoverd != nil { dc.Close() killDiscoverd() } if killEtcd != nil { killEtcd() } } }
func setup(t testutil.TestingT) (*discoverdWrapper, func()) { dc, killDiscoverd := testutil.BootDiscoverd(t, "") dw := &discoverdWrapper{discoverdClient: dc} return dw, func() { killDiscoverd() } }
func (s *S) SetUpSuite(c *C) { discd, killDiscoverd := testutil.BootDiscoverd(c, "", "") s.discd = discd s.cleanup = func() { killDiscoverd() } }
func newDiscoverd(t etcdrunner.TestingT) (discoverdClient, func()) { if *fake { return newFakeDiscoverd(), func() {} } discoverd, killDiscoverd := testutil.BootDiscoverd(t, "") return discoverd, func() { discoverd.Close() killDiscoverd() } }
func setup(t etcdrunner.TestingT) (*discoverdWrapper, func()) { etcdAddr, killEtcd := etcdrunner.RunEtcdServer(t) dc, killDiscoverd := testutil.BootDiscoverd(t, "", etcdAddr) dw := &discoverdWrapper{discoverdClient: dc} return dw, func() { killDiscoverd() killEtcd() } }
func (s *S) SetUpSuite(c *C) { etcdAddr, killEtcd := etcdrunner.RunEtcdServer(c) discd, killDiscoverd := testutil.BootDiscoverd(c, "", etcdAddr) s.discd = discd s.cleanup = func() { killDiscoverd() killEtcd() } }
func newTest(t *testing.T) (s *test) { defer func() { if t.Failed() { s.cleanup() t.FailNow() } }() client, killDiscoverd := testutil.BootDiscoverd(t, "") serviceName := "flannel-test" if err := client.AddService(serviceName, nil); err != nil { t.Errorf("error adding service: %s", err) } service := client.Service(serviceName) events := make(chan *discoverd.Event) stream, err := service.Watch(events) if err != nil { t.Errorf("error creating watch: %s", err) } data := []byte(`{"config":{"network": "10.3.0.0/16"}}`) if err := service.SetMeta(&discoverd.ServiceMeta{Data: data}); err != nil { t.Errorf("error setting meta: %s", err) } registry, err := NewRegistry(client, serviceName) if err != nil { t.Errorf("error creating registry: %s", err) } return &test{ T: t, client: client, service: service, events: events, registry: registry, cleanup: func() { stream.Close() killDiscoverd() }, } }
func (s *ClientSuite) TestWatchReconnect(c *C) { c.Skip("fix discoverd watch reconnect") // FIXME(benbjohnson) raftPort, err := testutil.RandomPort() c.Assert(err, IsNil) httpPort, err := testutil.RandomPort() c.Assert(err, IsNil) // clientA is used to register services and instances, and remains connected clientA, cleanup := testutil.SetupDiscoverd(c) defer cleanup() // clientB is connected to the server which will be restarted, and is used to // test that the watch generates the correct events after reconnecting clientB, killDiscoverd := testutil.BootDiscoverd(c, raftPort, httpPort) defer func() { killDiscoverd() }() // create a service with manual leader and some metadata service := "foo" config := &discoverd.ServiceConfig{LeaderType: discoverd.LeaderTypeManual} c.Assert(clientA.AddService(service, config), IsNil) serviceMeta := &discoverd.ServiceMeta{Data: []byte(`{"foo": "bar"}`)} c.Assert(clientA.Service(service).SetMeta(serviceMeta), IsNil) register := func(client *discoverd.Client, addr string, meta map[string]string) (discoverd.Heartbeater, *discoverd.Instance) { inst := &discoverd.Instance{Addr: addr, Proto: "tcp", Meta: meta} hb, err := client.RegisterInstance(service, inst) c.Assert(err, IsNil) return hb, inst } waitForEvent := func(events chan *discoverd.Event, addr string, kind discoverd.EventKind) { for { select { case e := <-events: if e.Kind == kind && (addr == "" || addr == e.Instance.Addr) { return } case <-time.After(10 * time.Second): c.Fatalf("timed out wating for %s event", kind) } } } waitForWatchState := func(ch chan discoverd.WatchState, state discoverd.WatchState) { for { select { case s := <-ch: if s == state { return } case <-time.After(10 * time.Second): c.Fatalf("timed out waiting for watch %s state", state) } } } // register three services register(clientA, ":1111", nil) hb2, _ := register(clientA, ":2222", map[string]string{"foo": "bar"}) hb3, _ := register(clientA, ":3333", nil) // create watches using both clients so we can synchronize assertions eventsA := make(chan *discoverd.Event) watchA, err := clientA.Service(service).Watch(eventsA) c.Assert(err, IsNil) defer watchA.Close() waitForEvent(eventsA, "", discoverd.EventKindCurrent) eventsB := make(chan *discoverd.Event) watchB, err := clientB.Service(service).Watch(eventsB) c.Assert(err, IsNil) defer watchB.Close() waitForEvent(eventsB, "", discoverd.EventKindCurrent) // kill clientB's server and wait for the watch to disconnect stateCh := make(chan discoverd.WatchState) watchB.(*discoverd.Watch).SetStateChannel(stateCh) killDiscoverd() waitForWatchState(stateCh, discoverd.WatchStateDisconnected) // make some changes using clientA // change some metadata c.Assert(hb2.SetMeta(map[string]string{"foo": "baz"}), IsNil) waitForEvent(eventsA, ":2222", discoverd.EventKindUpdate) // register a new instance _, inst := register(clientA, ":4444", nil) waitForEvent(eventsA, ":4444", discoverd.EventKindUp) // set a new leader clientA.Service(service).SetLeader(inst.ID) waitForEvent(eventsA, ":4444", discoverd.EventKindLeader) // unregister an instance hb3.Close() waitForEvent(eventsA, ":3333", discoverd.EventKindDown) // update the service metadata serviceMeta.Data = []byte(`{"foo": "baz"}`) c.Assert(clientA.Service(service).SetMeta(serviceMeta), IsNil) waitForEvent(eventsA, "", discoverd.EventKindServiceMeta) // restart clientB's server and wait for the watch to reconnect _, killDiscoverd = testutil.RunDiscoverdServer(c, raftPort, httpPort) waitForWatchState(stateCh, discoverd.WatchStateConnected) type expectedEvent struct { Addr string Kind discoverd.EventKind ServiceMeta *discoverd.ServiceMeta } assertCurrent := func(events chan *discoverd.Event, expected []*expectedEvent) { count := 0 isExpected := func(event *discoverd.Event) bool { for _, e := range expected { if e.Kind != event.Kind { continue } switch event.Kind { case discoverd.EventKindServiceMeta: if reflect.DeepEqual(event.ServiceMeta, e.ServiceMeta) { return true } default: if event.Instance != nil && event.Instance.Addr == e.Addr { return true } } } return false } for { select { case event := <-events: if event.Kind == discoverd.EventKindCurrent { if count != len(expected) { c.Fatalf("expected %d events, got %d", len(expected), count) } return } if !isExpected(event) { c.Fatalf("unexpected event: %+v", event) } count++ case <-time.After(10 * time.Second): c.Fatal("timed out waiting for events") } } } // check watchB emits missed events assertCurrent(eventsB, []*expectedEvent{ {Addr: ":2222", Kind: discoverd.EventKindUpdate}, {Addr: ":4444", Kind: discoverd.EventKindUp}, {Addr: ":4444", Kind: discoverd.EventKindLeader}, {Kind: discoverd.EventKindServiceMeta, ServiceMeta: serviceMeta}, {Addr: ":3333", Kind: discoverd.EventKindDown}, }) }
func TestReconnect(t *testing.T) { discoverdPort, err := etcdrunner.RandomPort() if err != nil { t.Fatal(err) } clientA, etcdAddr, cleanup := testutil.SetupDiscoverdWithEtcd(t) defer cleanup() clientB, killDiscoverd := testutil.BootDiscoverd(t, discoverdPort, etcdAddr) defer func() { clientB.UnregisterAll() clientB.Close() killDiscoverd() }() service1 := "serviceReconnect-1" service2 := "serviceReconnect-2" assert(clientA.Register(service1, ":1111"), t) assert(clientA.Register(service1, ":2222"), t) assert(clientA.Register(service2, ":1111"), t) assert(clientA.Register(service2, ":2222"), t) set1, err := clientB.NewServiceSet(service1) assert(err, t) waitUpdates(t, set1, true, 2)() set2, err := clientB.NewServiceSet(service2) assert(err, t) waitUpdates(t, set2, true, 2)() updates1 := set1.Watch(false) updates2 := set2.Watch(false) reconnCh := clientB.WatchReconnects() defer clientB.UnwatchReconnects(reconnCh) killDiscoverd() waitForConnStatus(t, reconnCh, discoverd.ConnStatusDisconnected) if err := clientB.Register(service1, ":3333"); err != discoverd.ErrDisconnected { t.Fatal("expected ErrDisconnected from clientB, got:", err) } if _, err := clientB.Services(service2, 1); err != discoverd.ErrDisconnected { t.Fatal("expected ErrDisconnected from clientB, got:", err) } assert(clientA.RegisterWithAttributes(service1, ":1111", map[string]string{"foo": "bar"}), t) assert(clientA.Unregister(service1, ":2222"), t) assert(clientA.Unregister(service2, ":1111"), t) assert(clientA.Register(service2, ":3333"), t) _, killDiscoverd = testutil.RunDiscoverdServer(t, discoverdPort, etcdAddr) waitForConnStatus(t, reconnCh, discoverd.ConnStatusConnected) // use goroutines to check for updates so slow watchers don't block the rpc stream updateErrors := make(chan error) go func() { updateErrors <- checkUpdates(updates1, []*agent.ServiceUpdate{ { Name: service1, Addr: "127.0.0.1:1111", Online: true, Attrs: map[string]string{"foo": "bar"}, }, { Name: service1, Addr: "127.0.0.1:2222", Online: false, }, }) }() go func() { updateErrors <- checkUpdates(updates2, []*agent.ServiceUpdate{ { Name: service2, Addr: "127.0.0.1:3333", Online: true, }, { Name: service2, Addr: "127.0.0.1:2222", Online: true, }, { Name: service2, Addr: "127.0.0.1:1111", Online: false, }, }) }() var updateError error for i := 0; i < 2; i++ { if err := <-updateErrors; err != nil && updateError == nil { updateError = err } } if updateError != nil { t.Fatal(updateError) } assert(clientA.Register(service1, ":3333"), t) if err := checkUpdates(updates1, []*agent.ServiceUpdate{{ Name: service1, Addr: "127.0.0.1:3333", Online: true, }}); err != nil { t.Fatal(err) } // wait for one heartbeat time.Sleep(agent.HeartbeatIntervalSecs*time.Second + time.Second) checkServices(t, set1.Services(), []*discoverd.Service{ {Name: service1, Host: "127.0.0.1", Port: "1111", Addr: "127.0.0.1:1111", Attrs: map[string]string{"foo": "bar"}}, {Name: service1, Host: "127.0.0.1", Port: "3333", Addr: "127.0.0.1:3333"}, }) checkServices(t, set2.Services(), []*discoverd.Service{ {Name: service2, Host: "127.0.0.1", Port: "2222", Addr: "127.0.0.1:2222"}, {Name: service2, Host: "127.0.0.1", Port: "3333", Addr: "127.0.0.1:3333"}, }) }