package eureka import ( "errors" "fmt" "reflect" "sync" "time" "github.com/go-kit/kit/log" "github.com/hudl/fargo" ) type testConnection struct { mu sync.RWMutex instances []*fargo.Instance errApplication error errHeartbeat error errRegister error errDeregister error } var ( errTest = errors.New("kaboom") errNotFound = &fargoUnsuccessfulHTTPResponse{statusCode: 404, messagePrefix: "not found"} loggerTest = log.NewNopLogger() appNameTest = "go-kit" instanceTest1 = &fargo.Instance{ HostName: "serveregistrar1.acme.org", Port: 8080, App: appNameTest, IPAddr: "192.168.0.1", VipAddress: "192.168.0.1", SecureVipAddress: "192.168.0.1", HealthCheckUrl: "http://serveregistrar1.acme.org:8080/healthz", StatusPageUrl: "http://serveregistrar1.acme.org:8080/status", HomePageUrl: "http://serveregistrar1.acme.org:8080/", Status: fargo.UP, DataCenterInfo: fargo.DataCenterInfo{Name: fargo.MyOwn}, LeaseInfo: fargo.LeaseInfo{RenewalIntervalInSecs: 1}, } instanceTest2 = &fargo.Instance{ HostName: "serveregistrar2.acme.org", Port: 8080, App: appNameTest, IPAddr: "192.168.0.2", VipAddress: "192.168.0.2", SecureVipAddress: "192.168.0.2", HealthCheckUrl: "http://serveregistrar2.acme.org:8080/healthz", StatusPageUrl: "http://serveregistrar2.acme.org:8080/status", HomePageUrl: "http://serveregistrar2.acme.org:8080/", Status: fargo.UP, DataCenterInfo: fargo.DataCenterInfo{Name: fargo.MyOwn}, } ) var _ fargoConnection = (*testConnection)(nil) func (c *testConnection) RegisterInstance(i *fargo.Instance) error { if c.errRegister != nil { return c.errRegister } c.mu.Lock() defer c.mu.Unlock() for _, instance := range c.instances { if reflect.DeepEqual(*instance, *i) { return errors.New("already registered") } } c.instances = append(c.instances, i) return nil } func (c *testConnection) HeartBeatInstance(i *fargo.Instance) error { return c.errHeartbeat } func (c *testConnection) DeregisterInstance(i *fargo.Instance) error { if c.errDeregister != nil { return c.errDeregister } c.mu.Lock() defer c.mu.Unlock() remaining := make([]*fargo.Instance, 0, len(c.instances)) for _, instance := range c.instances { if reflect.DeepEqual(*instance, *i) { continue } remaining = append(remaining, instance) } if len(remaining) == len(c.instances) { return errors.New("not registered") } c.instances = remaining return nil } func (c *testConnection) ReregisterInstance(ins *fargo.Instance) error { return nil } func (c *testConnection) instancesForApplication(name string) []*fargo.Instance { c.mu.RLock() defer c.mu.RUnlock() instances := make([]*fargo.Instance, 0, len(c.instances)) for _, i := range c.instances { if i.App == name { instances = append(instances, i) } } return instances } func (c *testConnection) GetApp(name string) (*fargo.Application, error) { if err := c.errApplication; err != nil { return nil, err } instances := c.instancesForApplication(name) if len(instances) == 0 { return nil, fmt.Errorf("application not found for name=%s", name) } return &fargo.Application{Name: name, Instances: instances}, nil } func (c *testConnection) ScheduleAppUpdates(name string, await bool, done <-chan struct{}) <-chan fargo.AppUpdate { updatec := make(chan fargo.AppUpdate, 1) send := func() { app, err := c.GetApp(name) select { case updatec <- fargo.AppUpdate{App: app, Err: err}: default: } } if await { send() } go func() { ticker := time.NewTicker(100 * time.Millisecond) for { select { case <-ticker.C: send() case <-done: ticker.Stop() return } } }() return updatec }