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...) }
|