influxdb/server_test.go

272 lines
7.3 KiB
Go
Raw Normal View History

2014-10-22 05:32:19 +00:00
package influxdb_test
import (
"fmt"
"io/ioutil"
"os"
"testing"
2014-10-25 19:30:41 +00:00
"code.google.com/p/go.crypto/bcrypt"
2014-10-22 05:32:19 +00:00
"github.com/influxdb/influxdb"
"github.com/influxdb/influxdb/messaging"
)
// Ensure the server can be successfully opened and closed.
func TestServer_Open(t *testing.T) {
c := NewMessagingClient()
s := NewServer(c)
defer s.Close()
2014-10-24 00:54:12 +00:00
if err := s.Server.Open(tempfile()); err != nil {
t.Fatal(err)
}
if err := s.Server.Close(); err != nil {
t.Fatal(err)
}
2014-10-22 05:32:19 +00:00
}
2014-10-25 15:17:08 +00:00
// Ensure an error is returned when opening an already open server.
func TestServer_Open_ErrServerOpen(t *testing.T) { t.Skip("pending") }
// Ensure an error is returned when opening a server without a path.
func TestServer_Open_ErrPathRequired(t *testing.T) { t.Skip("pending") }
2014-10-24 05:38:03 +00:00
// Ensure the server can create a database.
func TestServer_CreateDatabase(t *testing.T) {
2014-10-24 23:45:02 +00:00
s := OpenServer(NewMessagingClient())
2014-10-24 05:38:03 +00:00
defer s.Close()
// Create the "foo" database.
if err := s.CreateDatabase("foo"); err != nil {
t.Fatal(err)
}
// Verify that the database exists.
if d := s.Database("foo"); d == nil {
t.Fatalf("database not found")
} else if d.Name() != "foo" {
t.Fatalf("name mismatch: %s", d.Name())
}
}
2014-10-24 23:45:02 +00:00
// Ensure the server returns an error when creating a duplicate database.
func TestServer_CreateDatabase_ErrDatabaseExists(t *testing.T) {
s := OpenServer(NewMessagingClient())
defer s.Close()
// Create the "foo" database twice.
if err := s.CreateDatabase("foo"); err != nil {
t.Fatal(err)
}
if err := s.CreateDatabase("foo"); err != influxdb.ErrDatabaseExists {
t.Fatal(err)
}
}
// Ensure the server can drop a database.
func TestServer_DropDatabase(t *testing.T) {
s := OpenServer(NewMessagingClient())
defer s.Close()
// Create the "foo" database and verify it exists.
if err := s.CreateDatabase("foo"); err != nil {
t.Fatal(err)
} else if d := s.Database("foo"); d == nil {
t.Fatalf("database not actually created")
}
// Drop the "foo" database and verify that it's gone.
if err := s.DeleteDatabase("foo"); err != nil {
t.Fatal(err)
} else if d := s.Database("foo"); d != nil {
t.Fatalf("database not actually dropped")
}
}
// Ensure the server returns an error when dropping a database that doesn't exist.
func TestServer_DropDatabase_ErrDatabaseNotFound(t *testing.T) {
s := OpenServer(NewMessagingClient())
defer s.Close()
// Drop a database that doesn't exist.
if err := s.DeleteDatabase("no_such_db"); err != influxdb.ErrDatabaseNotFound {
t.Fatal(err)
}
}
2014-10-28 00:16:03 +00:00
// Ensure the server can return a list of all databases.
func TestServer_Databases(t *testing.T) {
s := OpenServer(NewMessagingClient())
defer s.Close()
// Create some databases.
s.CreateDatabase("foo")
s.CreateDatabase("bar")
// Return the databases.
if a := s.Databases(); len(a) != 2 {
t.Fatalf("unexpected db count: %d", len(a))
} else if a[0].Name() != "bar" {
t.Fatalf("unexpected db(0): %s", a[0].Name())
} else if a[1].Name() != "foo" {
t.Fatalf("unexpected db(1): %s", a[1].Name())
}
}
2014-10-28 23:54:49 +00:00
// Ensure the server can create a new cluster admin.
2014-10-29 00:43:03 +00:00
func TestServer_CreateClusterAdmin(t *testing.T) {
2014-10-28 23:54:49 +00:00
s := OpenServer(NewMessagingClient())
defer s.Close()
// Create a cluster admin.
if err := s.CreateClusterAdmin("susy", "pass"); err != nil {
2014-10-28 23:54:49 +00:00
t.Fatal(err)
}
// Verify that the admin exists.
if u := s.ClusterAdmin("susy"); u == nil {
t.Fatalf("admin not found")
} else if u.Name != "susy" {
t.Fatalf("username mismatch: %v", u.Name)
} else if bcrypt.CompareHashAndPassword([]byte(u.Hash), []byte("pass")) != nil {
t.Fatal("invalid password")
}
}
2014-10-29 00:43:03 +00:00
// Ensure the server returns an error when creating an admin without a name.
func TestServer_CreateClusterAdmin_ErrUsernameRequired(t *testing.T) {
s := OpenServer(NewMessagingClient())
defer s.Close()
if err := s.CreateClusterAdmin("", "pass"); err != influxdb.ErrUsernameRequired {
2014-10-29 00:43:03 +00:00
t.Fatal(err)
}
}
// Ensure the server returns an error when creating a duplicate admin.
func TestServer_CreateClusterAdmin_ErrClusterAdminExists(t *testing.T) {
s := OpenServer(NewMessagingClient())
defer s.Close()
if err := s.CreateClusterAdmin("susy", "pass"); err != nil {
2014-10-29 00:43:03 +00:00
t.Fatal(err)
}
if err := s.CreateClusterAdmin("susy", "pass"); err != influxdb.ErrClusterAdminExists {
2014-10-29 00:43:03 +00:00
t.Fatal(err)
}
}
// Ensure the server can delete an existing cluster admin.
func TestServer_DeleteClusterAdmin(t *testing.T) {
s := OpenServer(NewMessagingClient())
defer s.Close()
// Create a cluster admin.
if err := s.CreateClusterAdmin("susy", "pass"); err != nil {
2014-10-29 00:43:03 +00:00
t.Fatal(err)
} else if s.ClusterAdmin("susy") == nil {
t.Fatalf("admin not created")
}
// Delete the cluster admin.
if err := s.DeleteClusterAdmin("susy"); err != nil {
t.Fatal(err)
} else if s.ClusterAdmin("susy") != nil {
t.Fatalf("admin not actually deleted")
}
}
// Ensure the server can return a list of all admins.
func TestServer_ClusterAdmins(t *testing.T) {
s := OpenServer(NewMessagingClient())
defer s.Close()
// Create some databases.
s.CreateClusterAdmin("susy", "pass")
s.CreateClusterAdmin("john", "pass")
// Return the databases.
if a := s.ClusterAdmins(); len(a) != 2 {
t.Fatalf("unexpected admin count: %d", len(a))
} else if a[0].Name != "john" {
t.Fatalf("unexpected admin(0): %s", a[0].Name)
} else if a[1].Name != "susy" {
t.Fatalf("unexpected admin(1): %s", a[1].Name)
}
}
2014-10-22 05:32:19 +00:00
// Server is a wrapping test struct for influxdb.Server.
type Server struct {
*influxdb.Server
}
// NewServer returns a new test server instance.
func NewServer(client influxdb.MessagingClient) *Server {
return &Server{influxdb.NewServer(client)}
}
// OpenServer returns a new, open test server instance.
func OpenServer(client influxdb.MessagingClient) *Server {
s := NewServer(client)
if err := s.Open(tempfile()); err != nil {
panic(err.Error())
}
return s
}
// Close shuts down the server and removes all temporary files.
func (s *Server) Close() {
defer os.RemoveAll(s.Path())
s.Server.Close()
}
// MessagingClient represents a test client for the messaging broker.
type MessagingClient struct {
2014-10-24 05:38:03 +00:00
index uint64
c chan *messaging.Message
PublishFunc func(*messaging.Message) (uint64, error)
2014-10-22 05:32:19 +00:00
}
// NewMessagingClient returns a new instance of MessagingClient.
func NewMessagingClient() *MessagingClient {
2014-10-24 05:38:03 +00:00
c := &MessagingClient{c: make(chan *messaging.Message, 1)}
c.PublishFunc = c.send
return c
}
// Publish attaches an autoincrementing index to the message.
// This function also execute's the client's PublishFunc mock function.
func (c *MessagingClient) Publish(m *messaging.Message) (uint64, error) {
c.index++
m.Index = c.index
return c.PublishFunc(m)
}
// send sends the message through to the channel.
// This is the default value of PublishFunc.
func (c *MessagingClient) send(m *messaging.Message) (uint64, error) {
c.c <- m
return m.Index, nil
2014-10-22 05:32:19 +00:00
}
2014-10-24 05:38:03 +00:00
// C returns a channel for streaming message.
2014-10-22 05:32:19 +00:00
func (c *MessagingClient) C() <-chan *messaging.Message { return c.c }
// tempfile returns a temporary path.
func tempfile() string {
f, _ := ioutil.TempFile("", "influxdb-")
path := f.Name()
f.Close()
os.Remove(path)
return path
}
2014-10-30 00:21:17 +00:00
// errstr is an ease-of-use function to convert an error to a string.
func errstr(err error) string {
if err != nil {
return err.Error()
}
return ""
}
2014-10-22 05:32:19 +00:00
func warn(v ...interface{}) { fmt.Fprintln(os.Stderr, v...) }
func warnf(msg string, v ...interface{}) { fmt.Fprintf(os.Stderr, msg+"\n", v...) }