From 0ac8648ea948def5b20d69a5ce5aecca928d6c24 Mon Sep 17 00:00:00 2001 From: Matthew Jaffee Date: Fri, 12 Jan 2018 16:29:32 -0600 Subject: [PATCH 1/3] add NewServerCluster(size int) method to pilosa/test --- gossip/gossip.go | 5 +- test/pilosa.go | 112 ++++++++++++++++++++++++++++++++++++-------- test/pilosa_test.go | 49 +++++++++++++++++++ 3 files changed, 144 insertions(+), 22 deletions(-) create mode 100644 test/pilosa_test.go diff --git a/gossip/gossip.go b/gossip/gossip.go index 58c344b39..3afdabe31 100644 --- a/gossip/gossip.go +++ b/gossip/gossip.go @@ -26,6 +26,7 @@ import ( "github.com/hashicorp/memberlist" "github.com/pilosa/pilosa" "github.com/pilosa/pilosa/internal" + "github.com/pkg/errors" ) // Ensure GossipNodeSet implements interfaces. @@ -76,7 +77,7 @@ func (g *GossipNodeSet) Open() error { } ml, err := memberlist.Create(g.config.memberlistConfig) if err != nil { - return err + return errors.Wrap(err, "creating memberlist") } g.memberlist = ml g.broadcasts = &memberlist.TransmitLimitedQueue{ @@ -90,7 +91,7 @@ func (g *GossipNodeSet) Open() error { nodes := []*pilosa.Node{&pilosa.Node{Scheme: "gossip", Host: g.config.gossipSeed}} //TODO: support a list of seeds err = g.joinWithRetry(pilosa.Nodes(nodes).Hosts()) if err != nil { - return err + return errors.Wrap(err, "joinWithRetry") } return nil } diff --git a/test/pilosa.go b/test/pilosa.go index cb3f7a07a..9c541a6b8 100644 --- a/test/pilosa.go +++ b/test/pilosa.go @@ -8,41 +8,113 @@ import ( "testing" "github.com/pilosa/pilosa/server" + "github.com/pkg/errors" ) func MustNewRunningServer(t *testing.T) *server.Command { - s := server.NewCommand(&bytes.Buffer{}, ioutil.Discard, ioutil.Discard) - s.Config.Bind = ":0" - port := strconv.Itoa(MustOpenPort(t)) - s.Config.GossipPort = port - s.Config.GossipSeed = "localhost:" + port - td, err := ioutil.TempDir("", "") + s, err := newServer() if err != nil { - t.Fatalf("error creating temp data directory: %v", err) + t.Fatalf("getting new server: %v", err) } - s.Config.DataDir = td + err = s.Run() if err != nil { - t.Fatalf("error running new pilosa server: %v", err) + t.Fatalf("running new pilosa server: %v", err) } return s } -func MustOpenPort(t *testing.T) int { +func newServer() (*server.Command, error) { + s := server.NewCommand(&bytes.Buffer{}, ioutil.Discard, ioutil.Discard) + + port, err := openPort() + if err != nil { + return nil, errors.Wrap(err, "getting port") + } + s.Config.Bind = "localhost:" + strconv.Itoa(port) + + gport, err := openPort() + if err != nil { + return nil, errors.Wrap(err, "getting gossip port") + } + s.Config.GossipPort = strconv.Itoa(gport) + + s.Config.GossipSeed = "localhost:" + s.Config.GossipPort + s.Config.Cluster.Type = "gossip" + td, err := ioutil.TempDir("", "") + if err != nil { + return nil, errors.Wrap(err, "temp dir") + } + s.Config.DataDir = td + return s, nil +} + +func openPort() (int, error) { addr, err := net.ResolveTCPAddr("tcp", ":0") if err != nil { - t.Fatalf("resolving new port addr: %v", err) + return 0, errors.Wrap(err, "resolving new port addr") } - l, err := net.ListenTCP("tcp", addr) if err != nil { - t.Fatalf("listening to get new port: %v", err) + return 0, errors.Wrap(err, "listening to get new port") } - defer func() { - err := l.Close() - if err != nil { - t.Logf("error closing listener in MustOpenPort: %v", err) - } - }() - return l.Addr().(*net.TCPAddr).Port + port := l.Addr().(*net.TCPAddr).Port + err = l.Close() + if err != nil { + return port, errors.Wrap(err, "closing listener") + } + return port, nil + +} + +func MustOpenPort(t *testing.T) int { + port, err := openPort() + if err != nil { + t.Fatalf("allocating new port: %v", err) + } + return port +} + +type Cluster struct { + Servers []*server.Command +} + +func MustNewServerCluster(t *testing.T, size int) *Cluster { + cluster, err := NewServerCluster(size) + if err != nil { + t.Fatalf("new cluster: %v", err) + } + return cluster +} + +func NewServerCluster(size int) (cluster *Cluster, err error) { + cluster = &Cluster{ + Servers: make([]*server.Command, size), + } + hosts := make([]string, size) + for i := 0; i < size; i++ { + s, err := newServer() + if err != nil { + return nil, errors.Wrap(err, "new server") + } + cluster.Servers[i] = s + hosts[i] = s.Config.Bind + s.Config.GossipSeed = cluster.Servers[0].Config.GossipSeed + + } + + for _, s := range cluster.Servers { + s.Config.Cluster.Hosts = hosts + } + for i, s := range cluster.Servers { + err := s.Run() + if err != nil { + for j := 0; j <= i; j++ { + cluster.Servers[j].Close() + } + return nil, errors.Wrapf(err, "starting server %d of %d. Config: %#v", i+1, size, s.Config) + } + } + + return cluster, nil } diff --git a/test/pilosa_test.go b/test/pilosa_test.go new file mode 100644 index 000000000..78090a896 --- /dev/null +++ b/test/pilosa_test.go @@ -0,0 +1,49 @@ +package test_test + +import ( + "net/http" + "testing" + + "encoding/json" + + "github.com/pilosa/pilosa/test" +) + +func TestNewCluster(t *testing.T) { + cluster := test.MustNewServerCluster(t, 3) + response, err := http.Get("http://" + cluster.Servers[0].Server.Addr().String() + "/status") + if err != nil { + t.Fatalf("getting schema: %v", err) + } + dec := json.NewDecoder(response.Body) + a := StatusResp{} + err = dec.Decode(&a) + if err != nil { + t.Fatalf("decoding status response: %v", err) + } + + bytes, err := json.MarshalIndent(a, "", " ") + if err != nil { + t.Fatalf("encoding: %v", err) + } + + if len(a.Status.Nodes) != 3 { + t.Fatalf("wrong number of nodes in status: %s", bytes) + } + + for i, node := range a.Status.Nodes { + if node.State != "UP" { + t.Fatalf("node %d should be up but is %s", i, node.State) + } + } +} + +type StatusResp struct { + Status struct { + Nodes []struct { + Host string + Schema string + State string + } + } `json:"status"` +} From 673a2902558b7ff385387ed9f98871f7218bf8f2 Mon Sep 17 00:00:00 2001 From: Matthew Jaffee Date: Mon, 15 Jan 2018 10:40:36 -0600 Subject: [PATCH 2/3] make diagnostics false in cluster test --- test/pilosa.go | 1 + 1 file changed, 1 insertion(+) diff --git a/test/pilosa.go b/test/pilosa.go index 9c541a6b8..3443a925e 100644 --- a/test/pilosa.go +++ b/test/pilosa.go @@ -41,6 +41,7 @@ func newServer() (*server.Command, error) { s.Config.GossipSeed = "localhost:" + s.Config.GossipPort s.Config.Cluster.Type = "gossip" + s.Config.Metric.Diagnostics = false td, err := ioutil.TempDir("", "") if err != nil { return nil, errors.Wrap(err, "temp dir") From 5799c10cd1a9fdacc5766c0f6eddf0954bea0aa8 Mon Sep 17 00:00:00 2001 From: Matthew Jaffee Date: Tue, 16 Jan 2018 09:41:03 -0600 Subject: [PATCH 3/3] rename openPort, and some small refactors --- Gopkg.lock | 8 +++++++- test/pilosa.go | 10 +++++----- test/pilosa_test.go | 29 ++++++++++++++--------------- 3 files changed, 26 insertions(+), 21 deletions(-) diff --git a/Gopkg.lock b/Gopkg.lock index 24d6ce962..7837cadff 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -163,6 +163,12 @@ revision = "16398bac157da96aa88f98a2df640c7f32af1da2" version = "v1.0.1" +[[projects]] + name = "github.com/pkg/errors" + packages = ["."] + revision = "645ef00459ed84a119197bfb8d8205042c6df63d" + version = "v0.8.0" + [[projects]] name = "github.com/rakyll/statik" packages = ["fs"] @@ -262,6 +268,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "2e353a12454268d89afe6d06c6021631b577bfd62dede36458f34397ab34fa17" + inputs-digest = "d91110a10c830f7a9cc439b9578840d97d9921e84d08242316da8d4a18c68c56" solver-name = "gps-cdcl" solver-version = 1 diff --git a/test/pilosa.go b/test/pilosa.go index 3443a925e..d1bd45342 100644 --- a/test/pilosa.go +++ b/test/pilosa.go @@ -27,13 +27,13 @@ func MustNewRunningServer(t *testing.T) *server.Command { func newServer() (*server.Command, error) { s := server.NewCommand(&bytes.Buffer{}, ioutil.Discard, ioutil.Discard) - port, err := openPort() + port, err := findPort() if err != nil { return nil, errors.Wrap(err, "getting port") } s.Config.Bind = "localhost:" + strconv.Itoa(port) - gport, err := openPort() + gport, err := findPort() if err != nil { return nil, errors.Wrap(err, "getting gossip port") } @@ -50,7 +50,7 @@ func newServer() (*server.Command, error) { return s, nil } -func openPort() (int, error) { +func findPort() (int, error) { addr, err := net.ResolveTCPAddr("tcp", ":0") if err != nil { return 0, errors.Wrap(err, "resolving new port addr") @@ -68,8 +68,8 @@ func openPort() (int, error) { } -func MustOpenPort(t *testing.T) int { - port, err := openPort() +func MustFindPort(t *testing.T) int { + port, err := findPort() if err != nil { t.Fatalf("allocating new port: %v", err) } diff --git a/test/pilosa_test.go b/test/pilosa_test.go index 78090a896..20ae1df0d 100644 --- a/test/pilosa_test.go +++ b/test/pilosa_test.go @@ -16,34 +16,33 @@ func TestNewCluster(t *testing.T) { t.Fatalf("getting schema: %v", err) } dec := json.NewDecoder(response.Body) - a := StatusResp{} - err = dec.Decode(&a) + body := struct { + Status struct { + Nodes []struct { + Host string + Schema string + State string + } + } + }{} + + err = dec.Decode(&body) if err != nil { t.Fatalf("decoding status response: %v", err) } - bytes, err := json.MarshalIndent(a, "", " ") + bytes, err := json.MarshalIndent(body, "", " ") if err != nil { t.Fatalf("encoding: %v", err) } - if len(a.Status.Nodes) != 3 { + if len(body.Status.Nodes) != 3 { t.Fatalf("wrong number of nodes in status: %s", bytes) } - for i, node := range a.Status.Nodes { + for i, node := range body.Status.Nodes { if node.State != "UP" { t.Fatalf("node %d should be up but is %s", i, node.State) } } } - -type StatusResp struct { - Status struct { - Nodes []struct { - Host string - Schema string - State string - } - } `json:"status"` -}