Moved to google.golang.org/genproto/googleapis/api/annotations
Fixes #52
This commit is contained in:
39
vendor/github.com/go-kit/kit/sd/consul/client.go
generated
vendored
Normal file
39
vendor/github.com/go-kit/kit/sd/consul/client.go
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
package consul
|
||||
|
||||
import (
|
||||
consul "github.com/hashicorp/consul/api"
|
||||
)
|
||||
|
||||
// Client is a wrapper around the Consul API.
|
||||
type Client interface {
|
||||
// Register a service with the local agent.
|
||||
Register(r *consul.AgentServiceRegistration) error
|
||||
|
||||
// Deregister a service with the local agent.
|
||||
Deregister(r *consul.AgentServiceRegistration) error
|
||||
|
||||
// Service
|
||||
Service(service, tag string, passingOnly bool, queryOpts *consul.QueryOptions) ([]*consul.ServiceEntry, *consul.QueryMeta, error)
|
||||
}
|
||||
|
||||
type client struct {
|
||||
consul *consul.Client
|
||||
}
|
||||
|
||||
// NewClient returns an implementation of the Client interface, wrapping a
|
||||
// concrete Consul client.
|
||||
func NewClient(c *consul.Client) Client {
|
||||
return &client{consul: c}
|
||||
}
|
||||
|
||||
func (c *client) Register(r *consul.AgentServiceRegistration) error {
|
||||
return c.consul.Agent().ServiceRegister(r)
|
||||
}
|
||||
|
||||
func (c *client) Deregister(r *consul.AgentServiceRegistration) error {
|
||||
return c.consul.Agent().ServiceDeregister(r.ID)
|
||||
}
|
||||
|
||||
func (c *client) Service(service, tag string, passingOnly bool, queryOpts *consul.QueryOptions) ([]*consul.ServiceEntry, *consul.QueryMeta, error) {
|
||||
return c.consul.Health().Service(service, tag, passingOnly, queryOpts)
|
||||
}
|
156
vendor/github.com/go-kit/kit/sd/consul/client_test.go
generated
vendored
Normal file
156
vendor/github.com/go-kit/kit/sd/consul/client_test.go
generated
vendored
Normal file
@@ -0,0 +1,156 @@
|
||||
package consul
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"io"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
stdconsul "github.com/hashicorp/consul/api"
|
||||
|
||||
"github.com/go-kit/kit/endpoint"
|
||||
)
|
||||
|
||||
func TestClientRegistration(t *testing.T) {
|
||||
c := newTestClient(nil)
|
||||
|
||||
services, _, err := c.Service(testRegistration.Name, "", true, &stdconsul.QueryOptions{})
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if want, have := 0, len(services); want != have {
|
||||
t.Errorf("want %d, have %d", want, have)
|
||||
}
|
||||
|
||||
if err := c.Register(testRegistration); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
if err := c.Register(testRegistration); err == nil {
|
||||
t.Errorf("want error, have %v", err)
|
||||
}
|
||||
|
||||
services, _, err = c.Service(testRegistration.Name, "", true, &stdconsul.QueryOptions{})
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if want, have := 1, len(services); want != have {
|
||||
t.Errorf("want %d, have %d", want, have)
|
||||
}
|
||||
|
||||
if err := c.Deregister(testRegistration); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
if err := c.Deregister(testRegistration); err == nil {
|
||||
t.Errorf("want error, have %v", err)
|
||||
}
|
||||
|
||||
services, _, err = c.Service(testRegistration.Name, "", true, &stdconsul.QueryOptions{})
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if want, have := 0, len(services); want != have {
|
||||
t.Errorf("want %d, have %d", want, have)
|
||||
}
|
||||
}
|
||||
|
||||
type testClient struct {
|
||||
entries []*stdconsul.ServiceEntry
|
||||
}
|
||||
|
||||
func newTestClient(entries []*stdconsul.ServiceEntry) *testClient {
|
||||
return &testClient{
|
||||
entries: entries,
|
||||
}
|
||||
}
|
||||
|
||||
var _ Client = &testClient{}
|
||||
|
||||
func (c *testClient) Service(service, tag string, _ bool, opts *stdconsul.QueryOptions) ([]*stdconsul.ServiceEntry, *stdconsul.QueryMeta, error) {
|
||||
var results []*stdconsul.ServiceEntry
|
||||
|
||||
for _, entry := range c.entries {
|
||||
if entry.Service.Service != service {
|
||||
continue
|
||||
}
|
||||
if tag != "" {
|
||||
tagMap := map[string]struct{}{}
|
||||
|
||||
for _, t := range entry.Service.Tags {
|
||||
tagMap[t] = struct{}{}
|
||||
}
|
||||
|
||||
if _, ok := tagMap[tag]; !ok {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
results = append(results, entry)
|
||||
}
|
||||
|
||||
return results, &stdconsul.QueryMeta{}, nil
|
||||
}
|
||||
|
||||
func (c *testClient) Register(r *stdconsul.AgentServiceRegistration) error {
|
||||
toAdd := registration2entry(r)
|
||||
|
||||
for _, entry := range c.entries {
|
||||
if reflect.DeepEqual(*entry, *toAdd) {
|
||||
return errors.New("duplicate")
|
||||
}
|
||||
}
|
||||
|
||||
c.entries = append(c.entries, toAdd)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *testClient) Deregister(r *stdconsul.AgentServiceRegistration) error {
|
||||
toDelete := registration2entry(r)
|
||||
|
||||
var newEntries []*stdconsul.ServiceEntry
|
||||
for _, entry := range c.entries {
|
||||
if reflect.DeepEqual(*entry, *toDelete) {
|
||||
continue
|
||||
}
|
||||
newEntries = append(newEntries, entry)
|
||||
}
|
||||
if len(newEntries) == len(c.entries) {
|
||||
return errors.New("not found")
|
||||
}
|
||||
|
||||
c.entries = newEntries
|
||||
return nil
|
||||
}
|
||||
|
||||
func registration2entry(r *stdconsul.AgentServiceRegistration) *stdconsul.ServiceEntry {
|
||||
return &stdconsul.ServiceEntry{
|
||||
Node: &stdconsul.Node{
|
||||
Node: "some-node",
|
||||
Address: r.Address,
|
||||
},
|
||||
Service: &stdconsul.AgentService{
|
||||
ID: r.ID,
|
||||
Service: r.Name,
|
||||
Tags: r.Tags,
|
||||
Port: r.Port,
|
||||
Address: r.Address,
|
||||
},
|
||||
// Checks ignored
|
||||
}
|
||||
}
|
||||
|
||||
func testFactory(instance string) (endpoint.Endpoint, io.Closer, error) {
|
||||
return func(context.Context, interface{}) (interface{}, error) {
|
||||
return instance, nil
|
||||
}, nil, nil
|
||||
}
|
||||
|
||||
var testRegistration = &stdconsul.AgentServiceRegistration{
|
||||
ID: "my-id",
|
||||
Name: "my-name",
|
||||
Tags: []string{"my-tag-1", "my-tag-2"},
|
||||
Port: 12345,
|
||||
Address: "my-address",
|
||||
}
|
2
vendor/github.com/go-kit/kit/sd/consul/doc.go
generated
vendored
Normal file
2
vendor/github.com/go-kit/kit/sd/consul/doc.go
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
// Package consul provides subscriber and registrar implementations for Consul.
|
||||
package consul
|
81
vendor/github.com/go-kit/kit/sd/consul/integration_test.go
generated
vendored
Normal file
81
vendor/github.com/go-kit/kit/sd/consul/integration_test.go
generated
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
// +build integration
|
||||
|
||||
package consul
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/go-kit/kit/endpoint"
|
||||
"github.com/go-kit/kit/log"
|
||||
stdconsul "github.com/hashicorp/consul/api"
|
||||
)
|
||||
|
||||
func TestIntegration(t *testing.T) {
|
||||
consulAddr := os.Getenv("CONSUL_ADDR")
|
||||
if consulAddr == "" {
|
||||
t.Fatal("CONSUL_ADDR is not set")
|
||||
}
|
||||
stdClient, err := stdconsul.NewClient(&stdconsul.Config{
|
||||
Address: consulAddr,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
client := NewClient(stdClient)
|
||||
logger := log.NewLogfmtLogger(os.Stderr)
|
||||
|
||||
// Produce a fake service registration.
|
||||
r := &stdconsul.AgentServiceRegistration{
|
||||
ID: "my-service-ID",
|
||||
Name: "my-service-name",
|
||||
Tags: []string{"alpha", "beta"},
|
||||
Port: 12345,
|
||||
Address: "my-address",
|
||||
EnableTagOverride: false,
|
||||
// skipping check(s)
|
||||
}
|
||||
|
||||
// Build a subscriber on r.Name + r.Tags.
|
||||
factory := func(instance string) (endpoint.Endpoint, io.Closer, error) {
|
||||
t.Logf("factory invoked for %q", instance)
|
||||
return endpoint.Nop, nil, nil
|
||||
}
|
||||
subscriber := NewSubscriber(
|
||||
client,
|
||||
factory,
|
||||
log.With(logger, "component", "subscriber"),
|
||||
r.Name,
|
||||
r.Tags,
|
||||
true,
|
||||
)
|
||||
|
||||
time.Sleep(time.Second)
|
||||
|
||||
// Before we publish, we should have no endpoints.
|
||||
endpoints, err := subscriber.Endpoints()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if want, have := 0, len(endpoints); want != have {
|
||||
t.Errorf("want %d, have %d", want, have)
|
||||
}
|
||||
|
||||
// Build a registrar for r.
|
||||
registrar := NewRegistrar(client, r, log.With(logger, "component", "registrar"))
|
||||
registrar.Register()
|
||||
defer registrar.Deregister()
|
||||
|
||||
time.Sleep(time.Second)
|
||||
|
||||
// Now we should have one active endpoints.
|
||||
endpoints, err = subscriber.Endpoints()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if want, have := 1, len(endpoints); want != have {
|
||||
t.Errorf("want %d, have %d", want, have)
|
||||
}
|
||||
}
|
44
vendor/github.com/go-kit/kit/sd/consul/registrar.go
generated
vendored
Normal file
44
vendor/github.com/go-kit/kit/sd/consul/registrar.go
generated
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
package consul
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
stdconsul "github.com/hashicorp/consul/api"
|
||||
|
||||
"github.com/go-kit/kit/log"
|
||||
)
|
||||
|
||||
// Registrar registers service instance liveness information to Consul.
|
||||
type Registrar struct {
|
||||
client Client
|
||||
registration *stdconsul.AgentServiceRegistration
|
||||
logger log.Logger
|
||||
}
|
||||
|
||||
// NewRegistrar returns a Consul Registrar acting on the provided catalog
|
||||
// registration.
|
||||
func NewRegistrar(client Client, r *stdconsul.AgentServiceRegistration, logger log.Logger) *Registrar {
|
||||
return &Registrar{
|
||||
client: client,
|
||||
registration: r,
|
||||
logger: log.With(logger, "service", r.Name, "tags", fmt.Sprint(r.Tags), "address", r.Address),
|
||||
}
|
||||
}
|
||||
|
||||
// Register implements sd.Registrar interface.
|
||||
func (p *Registrar) Register() {
|
||||
if err := p.client.Register(p.registration); err != nil {
|
||||
p.logger.Log("err", err)
|
||||
} else {
|
||||
p.logger.Log("action", "register")
|
||||
}
|
||||
}
|
||||
|
||||
// Deregister implements sd.Registrar interface.
|
||||
func (p *Registrar) Deregister() {
|
||||
if err := p.client.Deregister(p.registration); err != nil {
|
||||
p.logger.Log("err", err)
|
||||
} else {
|
||||
p.logger.Log("action", "deregister")
|
||||
}
|
||||
}
|
27
vendor/github.com/go-kit/kit/sd/consul/registrar_test.go
generated
vendored
Normal file
27
vendor/github.com/go-kit/kit/sd/consul/registrar_test.go
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
package consul
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
stdconsul "github.com/hashicorp/consul/api"
|
||||
|
||||
"github.com/go-kit/kit/log"
|
||||
)
|
||||
|
||||
func TestRegistrar(t *testing.T) {
|
||||
client := newTestClient([]*stdconsul.ServiceEntry{})
|
||||
p := NewRegistrar(client, testRegistration, log.NewNopLogger())
|
||||
if want, have := 0, len(client.entries); want != have {
|
||||
t.Errorf("want %d, have %d", want, have)
|
||||
}
|
||||
|
||||
p.Register()
|
||||
if want, have := 1, len(client.entries); want != have {
|
||||
t.Errorf("want %d, have %d", want, have)
|
||||
}
|
||||
|
||||
p.Deregister()
|
||||
if want, have := 0, len(client.entries); want != have {
|
||||
t.Errorf("want %d, have %d", want, have)
|
||||
}
|
||||
}
|
166
vendor/github.com/go-kit/kit/sd/consul/subscriber.go
generated
vendored
Normal file
166
vendor/github.com/go-kit/kit/sd/consul/subscriber.go
generated
vendored
Normal file
@@ -0,0 +1,166 @@
|
||||
package consul
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
consul "github.com/hashicorp/consul/api"
|
||||
|
||||
"github.com/go-kit/kit/endpoint"
|
||||
"github.com/go-kit/kit/log"
|
||||
"github.com/go-kit/kit/sd"
|
||||
"github.com/go-kit/kit/sd/cache"
|
||||
)
|
||||
|
||||
const defaultIndex = 0
|
||||
|
||||
// Subscriber yields endpoints for a service in Consul. Updates to the service
|
||||
// are watched and will update the Subscriber endpoints.
|
||||
type Subscriber struct {
|
||||
cache *cache.Cache
|
||||
client Client
|
||||
logger log.Logger
|
||||
service string
|
||||
tags []string
|
||||
passingOnly bool
|
||||
endpointsc chan []endpoint.Endpoint
|
||||
quitc chan struct{}
|
||||
}
|
||||
|
||||
var _ sd.Subscriber = &Subscriber{}
|
||||
|
||||
// NewSubscriber returns a Consul subscriber which returns endpoints for the
|
||||
// requested service. It only returns instances for which all of the passed tags
|
||||
// are present.
|
||||
func NewSubscriber(client Client, factory sd.Factory, logger log.Logger, service string, tags []string, passingOnly bool) *Subscriber {
|
||||
s := &Subscriber{
|
||||
cache: cache.New(factory, logger),
|
||||
client: client,
|
||||
logger: log.With(logger, "service", service, "tags", fmt.Sprint(tags)),
|
||||
service: service,
|
||||
tags: tags,
|
||||
passingOnly: passingOnly,
|
||||
quitc: make(chan struct{}),
|
||||
}
|
||||
|
||||
instances, index, err := s.getInstances(defaultIndex, nil)
|
||||
if err == nil {
|
||||
s.logger.Log("instances", len(instances))
|
||||
} else {
|
||||
s.logger.Log("err", err)
|
||||
}
|
||||
|
||||
s.cache.Update(instances)
|
||||
go s.loop(index)
|
||||
return s
|
||||
}
|
||||
|
||||
// Endpoints implements the Subscriber interface.
|
||||
func (s *Subscriber) Endpoints() ([]endpoint.Endpoint, error) {
|
||||
return s.cache.Endpoints(), nil
|
||||
}
|
||||
|
||||
// Stop terminates the subscriber.
|
||||
func (s *Subscriber) Stop() {
|
||||
close(s.quitc)
|
||||
}
|
||||
|
||||
func (s *Subscriber) loop(lastIndex uint64) {
|
||||
var (
|
||||
instances []string
|
||||
err error
|
||||
)
|
||||
for {
|
||||
instances, lastIndex, err = s.getInstances(lastIndex, s.quitc)
|
||||
switch {
|
||||
case err == io.EOF:
|
||||
return // stopped via quitc
|
||||
case err != nil:
|
||||
s.logger.Log("err", err)
|
||||
default:
|
||||
s.cache.Update(instances)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Subscriber) getInstances(lastIndex uint64, interruptc chan struct{}) ([]string, uint64, error) {
|
||||
tag := ""
|
||||
if len(s.tags) > 0 {
|
||||
tag = s.tags[0]
|
||||
}
|
||||
|
||||
// Consul doesn't support more than one tag in its service query method.
|
||||
// https://github.com/hashicorp/consul/issues/294
|
||||
// Hashi suggest prepared queries, but they don't support blocking.
|
||||
// https://www.consul.io/docs/agent/http/query.html#execute
|
||||
// If we want blocking for efficiency, we must filter tags manually.
|
||||
|
||||
type response struct {
|
||||
instances []string
|
||||
index uint64
|
||||
}
|
||||
|
||||
var (
|
||||
errc = make(chan error, 1)
|
||||
resc = make(chan response, 1)
|
||||
)
|
||||
|
||||
go func() {
|
||||
entries, meta, err := s.client.Service(s.service, tag, s.passingOnly, &consul.QueryOptions{
|
||||
WaitIndex: lastIndex,
|
||||
})
|
||||
if err != nil {
|
||||
errc <- err
|
||||
return
|
||||
}
|
||||
if len(s.tags) > 1 {
|
||||
entries = filterEntries(entries, s.tags[1:]...)
|
||||
}
|
||||
resc <- response{
|
||||
instances: makeInstances(entries),
|
||||
index: meta.LastIndex,
|
||||
}
|
||||
}()
|
||||
|
||||
select {
|
||||
case err := <-errc:
|
||||
return nil, 0, err
|
||||
case res := <-resc:
|
||||
return res.instances, res.index, nil
|
||||
case <-interruptc:
|
||||
return nil, 0, io.EOF
|
||||
}
|
||||
}
|
||||
|
||||
func filterEntries(entries []*consul.ServiceEntry, tags ...string) []*consul.ServiceEntry {
|
||||
var es []*consul.ServiceEntry
|
||||
|
||||
ENTRIES:
|
||||
for _, entry := range entries {
|
||||
ts := make(map[string]struct{}, len(entry.Service.Tags))
|
||||
for _, tag := range entry.Service.Tags {
|
||||
ts[tag] = struct{}{}
|
||||
}
|
||||
|
||||
for _, tag := range tags {
|
||||
if _, ok := ts[tag]; !ok {
|
||||
continue ENTRIES
|
||||
}
|
||||
}
|
||||
es = append(es, entry)
|
||||
}
|
||||
|
||||
return es
|
||||
}
|
||||
|
||||
func makeInstances(entries []*consul.ServiceEntry) []string {
|
||||
instances := make([]string, len(entries))
|
||||
for i, entry := range entries {
|
||||
addr := entry.Node.Address
|
||||
if entry.Service.Address != "" {
|
||||
addr = entry.Service.Address
|
||||
}
|
||||
instances[i] = fmt.Sprintf("%s:%d", addr, entry.Service.Port)
|
||||
}
|
||||
return instances
|
||||
}
|
138
vendor/github.com/go-kit/kit/sd/consul/subscriber_test.go
generated
vendored
Normal file
138
vendor/github.com/go-kit/kit/sd/consul/subscriber_test.go
generated
vendored
Normal file
@@ -0,0 +1,138 @@
|
||||
package consul
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
consul "github.com/hashicorp/consul/api"
|
||||
|
||||
"github.com/go-kit/kit/log"
|
||||
)
|
||||
|
||||
var consulState = []*consul.ServiceEntry{
|
||||
{
|
||||
Node: &consul.Node{
|
||||
Address: "10.0.0.0",
|
||||
Node: "app00.local",
|
||||
},
|
||||
Service: &consul.AgentService{
|
||||
ID: "search-api-0",
|
||||
Port: 8000,
|
||||
Service: "search",
|
||||
Tags: []string{
|
||||
"api",
|
||||
"v1",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Node: &consul.Node{
|
||||
Address: "10.0.0.1",
|
||||
Node: "app01.local",
|
||||
},
|
||||
Service: &consul.AgentService{
|
||||
ID: "search-api-1",
|
||||
Port: 8001,
|
||||
Service: "search",
|
||||
Tags: []string{
|
||||
"api",
|
||||
"v2",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Node: &consul.Node{
|
||||
Address: "10.0.0.1",
|
||||
Node: "app01.local",
|
||||
},
|
||||
Service: &consul.AgentService{
|
||||
Address: "10.0.0.10",
|
||||
ID: "search-db-0",
|
||||
Port: 9000,
|
||||
Service: "search",
|
||||
Tags: []string{
|
||||
"db",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func TestSubscriber(t *testing.T) {
|
||||
var (
|
||||
logger = log.NewNopLogger()
|
||||
client = newTestClient(consulState)
|
||||
)
|
||||
|
||||
s := NewSubscriber(client, testFactory, logger, "search", []string{"api"}, true)
|
||||
defer s.Stop()
|
||||
|
||||
endpoints, err := s.Endpoints()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if want, have := 2, len(endpoints); want != have {
|
||||
t.Errorf("want %d, have %d", want, have)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSubscriberNoService(t *testing.T) {
|
||||
var (
|
||||
logger = log.NewNopLogger()
|
||||
client = newTestClient(consulState)
|
||||
)
|
||||
|
||||
s := NewSubscriber(client, testFactory, logger, "feed", []string{}, true)
|
||||
defer s.Stop()
|
||||
|
||||
endpoints, err := s.Endpoints()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if want, have := 0, len(endpoints); want != have {
|
||||
t.Fatalf("want %d, have %d", want, have)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSubscriberWithTags(t *testing.T) {
|
||||
var (
|
||||
logger = log.NewNopLogger()
|
||||
client = newTestClient(consulState)
|
||||
)
|
||||
|
||||
s := NewSubscriber(client, testFactory, logger, "search", []string{"api", "v2"}, true)
|
||||
defer s.Stop()
|
||||
|
||||
endpoints, err := s.Endpoints()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if want, have := 1, len(endpoints); want != have {
|
||||
t.Fatalf("want %d, have %d", want, have)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSubscriberAddressOverride(t *testing.T) {
|
||||
s := NewSubscriber(newTestClient(consulState), testFactory, log.NewNopLogger(), "search", []string{"db"}, true)
|
||||
defer s.Stop()
|
||||
|
||||
endpoints, err := s.Endpoints()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if want, have := 1, len(endpoints); want != have {
|
||||
t.Fatalf("want %d, have %d", want, have)
|
||||
}
|
||||
|
||||
response, err := endpoints[0](context.Background(), struct{}{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if want, have := "10.0.0.10:9000", response.(string); want != have {
|
||||
t.Errorf("want %q, have %q", want, have)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user