func addGroup(st store.Store, serviceName string, addr *data.AddressSpec, labels ...string) { if len(labels)%2 != 0 { panic("Expected key value ... as arguments") } sel := make(map[string]string) for i := 0; i < len(labels); i += 2 { sel[labels[i]] = labels[i+1] } if addr == nil { addr = &data.AddressSpec{"fixed", 80} } st.SetContainerRule(serviceName, GROUP, data.ContainerRule{*addr, sel}) }
func testRules(s store.Store, t *testing.T) { require.Nil(t, s.AddService("svc", testService)) require.Nil(t, s.SetContainerRule("svc", "group", testRule)) svc, err := s.GetService("svc", store.QueryServiceOptions{WithContainerRules: true}) require.Nil(t, err) require.Equal(t, []store.ContainerRuleInfo{ store.ContainerRuleInfo{ Name: "group", ContainerRule: testRule, }, }, svc.ContainerRules) require.Nil(t, s.RemoveContainerRule("svc", "group")) svc, err = s.GetService("svc", store.QueryServiceOptions{WithContainerRules: true}) require.Nil(t, err) require.Empty(t, svc.ContainerRules) }
func testInstances(s store.Store, t *testing.T) { require.Nil(t, s.AddService("svc", testService)) require.Nil(t, s.AddInstance("svc", "inst", testInst)) instances := func() map[string]data.Instance { insts := make(map[string]data.Instance) require.Nil(t, store.ForeachInstance(s, "svc", func(_, n string, inst data.Instance) error { insts[n] = inst return nil })) return insts } require.Equal(t, map[string]data.Instance{"inst": testInst}, instances()) serviceInstances := func() map[string]data.Instance { insts := make(map[string]data.Instance) require.Nil(t, store.ForeachServiceInstance(s, nil, func(sn string, in string, inst data.Instance) error { insts[sn+" "+in] = inst return nil })) return insts } require.Equal(t, map[string]data.Instance{"svc inst": testInst}, serviceInstances()) require.Nil(t, s.RemoveInstance("svc", "inst")) require.Equal(t, map[string]data.Instance{}, instances()) require.Equal(t, map[string]data.Instance{}, serviceInstances()) }
func newWatcher(s store.Store, opts store.QueryServiceOptions) *watcher { w := &watcher{stopCh: make(chan struct{}), done: make(chan struct{})} changes := make(chan data.ServiceChange) ctx, cancel := context.WithCancel(context.Background()) s.WatchServices(ctx, changes, daemon.NewErrorSink(), opts) go func() { defer close(w.done) for { select { case change := <-changes: w.changes = append(w.changes, change) case <-w.stopCh: cancel() return } } }() return w }
func allServices(t *testing.T, st store.Store) []*store.ServiceInfo { services, err := st.GetAllServices(store.QueryServiceOptions{}) require.NoError(t, err) return services }
func testServices(s store.Store, t *testing.T) { require.Nil(t, s.AddService("svc", testService)) svc2, err := s.GetService("svc", store.QueryServiceOptions{}) require.Nil(t, err) require.Equal(t, "svc", svc2.Name) require.Equal(t, testService, svc2.Service) require.Nil(t, s.CheckRegisteredService("svc")) services := func() map[string]data.Service { svcs := make(map[string]data.Service) ss, err := s.GetAllServices(store.QueryServiceOptions{}) require.Nil(t, err) for _, svc := range ss { svcs[svc.Name] = svc.Service } return svcs } require.Equal(t, map[string]data.Service{"svc": testService}, services()) require.Nil(t, s.RemoveService("svc")) require.Equal(t, map[string]data.Service{}, services()) require.Nil(t, s.AddService("svc", testService)) require.Nil(t, s.RemoveAllServices()) require.Equal(t, map[string]data.Service{}, services()) }
func testPing(s store.Store, t *testing.T) { require.Nil(t, s.Ping()) }
func testWatchServices(s store.Store, t *testing.T) { check := func(opts store.QueryServiceOptions, body func(w *watcher), changes ...data.ServiceChange) { w := newWatcher(s, opts) body(w) // Yuck. There's a race between making a change in // etcd, and hearing about it via the watch, and I // haven't found a nicer way to avoid it. time.Sleep(100 * time.Millisecond) w.stop() require.Equal(t, changes, w.changes) require.Nil(t, s.RemoveAllServices()) } check(store.QueryServiceOptions{}, func(w *watcher) { require.Nil(t, s.AddService("svc", testService)) }, data.ServiceChange{"svc", false}) require.Nil(t, s.AddService("svc", testService)) check(store.QueryServiceOptions{}, func(w *watcher) { require.Nil(t, s.RemoveAllServices()) require.Nil(t, s.AddService("svc", testService)) require.Nil(t, s.RemoveService("svc")) }, data.ServiceChange{"svc", true}, data.ServiceChange{"svc", false}, data.ServiceChange{"svc", true}) // WithInstances false, so adding an instance should not // cause an event require.Nil(t, s.AddService("svc", testService)) check(store.QueryServiceOptions{}, func(w *watcher) { require.Nil(t, s.AddInstance("svc", "inst", testInst)) }) // WithInstances true, so instance changes should // cause events require.Nil(t, s.AddService("svc", testService)) check(store.QueryServiceOptions{WithInstances: true}, func(w *watcher) { require.Nil(t, s.AddInstance("svc", "inst", testInst)) require.Nil(t, s.RemoveInstance("svc", "inst")) }, data.ServiceChange{"svc", false}, data.ServiceChange{"svc", false}) // WithContainerRules false, so adding a rule should not // cause an event require.Nil(t, s.AddService("svc", testService)) check(store.QueryServiceOptions{}, func(w *watcher) { require.Nil(t, s.SetContainerRule("svc", "group", testRule)) }) // WithContainerRules true, so instance changes should // cause events require.Nil(t, s.AddService("svc", testService)) check(store.QueryServiceOptions{WithContainerRules: true}, func(w *watcher) { require.Nil(t, s.SetContainerRule("svc", "group", testRule)) require.Nil(t, s.RemoveContainerRule("svc", "group")) }, data.ServiceChange{"svc", false}, data.ServiceChange{"svc", false}) }