influxdb/server_test.go

313 lines
8.3 KiB
Go
Raw Normal View History

2014-10-22 05:32:19 +00:00
package influxdb_test
import (
"fmt"
"io/ioutil"
"os"
2014-10-25 04:38:01 +00:00
"reflect"
2014-10-22 05:32:19 +00:00
"testing"
"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-25 04:38:01 +00:00
// Ensure the server can create a new user.
func TestServer_CreateUser(t *testing.T) {
s := OpenServer(NewMessagingClient())
defer s.Close()
// Create a database.
if err := s.CreateDatabase("foo"); err != nil {
t.Fatal(err)
}
db := s.Database("foo")
// Create a user on the database.
if err := db.CreateUser("susy", "pass", nil); err != nil {
t.Fatal(err)
}
// Verify that the user exists.
if u := db.User("susy"); u == nil {
t.Fatalf("user not found")
} else if reflect.DeepEqual(u, nil) {
t.Fatalf("user mismatch: %#v", u)
}
}
2014-10-25 15:17:08 +00:00
// Ensure the server returns an error when creating a user without a name.
func TestServer_CreateUser_ErrUsernameRequired(t *testing.T) {
s := OpenServer(NewMessagingClient())
defer s.Close()
if err := s.CreateDatabase("foo"); err != nil {
t.Fatal(err)
}
if err := s.Database("foo").CreateUser("", "pass", nil); err != influxdb.ErrUsernameRequired {
t.Fatal(err)
}
}
// Ensure the server returns an error when creating a user with an invalid name.
func TestServer_CreateUser_ErrInvalidUsername(t *testing.T) {
s := OpenServer(NewMessagingClient())
defer s.Close()
if err := s.CreateDatabase("foo"); err != nil {
t.Fatal(err)
}
if err := s.Database("foo").CreateUser("my%user", "pass", nil); err != influxdb.ErrInvalidUsername {
t.Fatal(err)
}
}
// Ensure the server returns an error when creating a user after the db is dropped.
func TestServer_CreateUser_ErrDatabaseNotFound(t *testing.T) {
s := OpenServer(NewMessagingClient())
defer s.Close()
// Create database.
if err := s.CreateDatabase("foo"); err != nil {
t.Fatal(err)
}
db := s.Database("foo")
// Drop the database.
if err := s.DeleteDatabase("foo"); err != nil {
t.Fatal(err)
}
// Create a user using the old database reference.
if err := db.CreateUser("susy", "pass", nil); err != influxdb.ErrDatabaseNotFound {
t.Fatal(err)
}
}
// Ensure the server returns an error when creating a duplicate user.
func TestServer_CreateUser_ErrUserExists(t *testing.T) {
s := OpenServer(NewMessagingClient())
defer s.Close()
// Create database.
if err := s.CreateDatabase("foo"); err != nil {
t.Fatal(err)
}
db := s.Database("foo")
// Create a user a user. Then create the user again.
if err := db.CreateUser("susy", "pass", nil); err != nil {
t.Fatal(err)
}
if err := db.CreateUser("susy", "pass", nil); err != influxdb.ErrUserExists {
t.Fatal(err)
}
}
2014-10-25 17:54:23 +00:00
// Ensure the server can delete an existing user.
func TestServer_DeleteUser(t *testing.T) {
s := OpenServer(NewMessagingClient())
defer s.Close()
// Create a database and user.
s.CreateDatabase("foo")
db := s.Database("foo")
if err := db.CreateUser("susy", "pass", nil); err != nil {
t.Fatal(err)
} else if db.User("susy") == nil {
t.Fatal("user not created")
}
// Remove user from database.
if err := db.DeleteUser("susy"); err != nil {
t.Fatal(err)
} else if db.User("susy") != nil {
t.Fatal("user not deleted")
}
}
// Ensure the server returns an error when delete a user without a name.
func TestServer_DeleteUser_ErrUsernameRequired(t *testing.T) {
s := OpenServer(NewMessagingClient())
defer s.Close()
s.CreateDatabase("foo")
if err := s.Database("foo").DeleteUser(""); err != influxdb.ErrUsernameRequired {
t.Fatal(err)
}
}
// Ensure the server returns an error when deleting a user after the db is dropped.
func TestServer_DeleteUser_ErrDatabaseNotFound(t *testing.T) {
s := OpenServer(NewMessagingClient())
defer s.Close()
// Create & delete the database.
s.CreateDatabase("foo")
db := s.Database("foo")
s.DeleteDatabase("foo")
// Delete a user using the old database reference.
if err := db.DeleteUser("susy"); err != influxdb.ErrDatabaseNotFound {
t.Fatal(err)
}
}
// Ensure the server returns an error when deleting a non-existent user.
func TestServer_DeleteUser_ErrUserNotFound(t *testing.T) {
s := OpenServer(NewMessagingClient())
defer s.Close()
s.CreateDatabase("foo")
if err := s.Database("foo").DeleteUser("no_such_user"); err != influxdb.ErrUserNotFound {
t.Fatal(err)
}
}
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
}
func warn(v ...interface{}) { fmt.Fprintln(os.Stderr, v...) }
func warnf(msg string, v ...interface{}) { fmt.Fprintf(os.Stderr, msg+"\n", v...) }