2014-10-22 05:32:19 +00:00
|
|
|
package influxdb_test
|
|
|
|
|
|
|
|
import (
|
2014-12-24 04:46:54 +00:00
|
|
|
"encoding/json"
|
2014-10-22 05:32:19 +00:00
|
|
|
"fmt"
|
|
|
|
"io/ioutil"
|
2014-12-29 23:12:51 +00:00
|
|
|
"net/url"
|
2014-10-22 05:32:19 +00:00
|
|
|
"os"
|
2014-12-23 06:18:05 +00:00
|
|
|
"reflect"
|
2015-01-14 23:44:09 +00:00
|
|
|
"strings"
|
2014-10-22 05:32:19 +00:00
|
|
|
"testing"
|
2014-11-10 02:55:53 +00:00
|
|
|
"time"
|
2014-10-22 05:32:19 +00:00
|
|
|
|
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"
|
2015-01-14 23:44:09 +00:00
|
|
|
"github.com/influxdb/influxdb/influxql"
|
2014-10-22 05:32:19 +00:00
|
|
|
"github.com/influxdb/influxdb/messaging"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Ensure the server can be successfully opened and closed.
|
|
|
|
func TestServer_Open(t *testing.T) {
|
2014-12-30 22:46:50 +00:00
|
|
|
s := NewServer()
|
2014-10-22 05:32:19 +00:00
|
|
|
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-12-29 23:12:51 +00:00
|
|
|
// Ensure the server can create a new data node.
|
2014-12-30 15:50:15 +00:00
|
|
|
func TestServer_CreateDataNode(t *testing.T) {
|
2014-12-29 23:12:51 +00:00
|
|
|
s := OpenServer(NewMessagingClient())
|
|
|
|
defer s.Close()
|
|
|
|
|
|
|
|
// Create a new node.
|
|
|
|
u, _ := url.Parse("http://localhost:80000")
|
2014-12-30 15:50:15 +00:00
|
|
|
if err := s.CreateDataNode(u); err != nil {
|
2014-12-29 23:12:51 +00:00
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
s.Restart()
|
|
|
|
|
|
|
|
// Verify that the node exists.
|
2014-12-30 15:50:15 +00:00
|
|
|
if n := s.DataNodeByURL(u); n == nil {
|
|
|
|
t.Fatalf("data node not found")
|
2014-12-29 23:12:51 +00:00
|
|
|
} else if n.URL.String() != "http://localhost:80000" {
|
|
|
|
t.Fatalf("unexpected url: %s", n.URL)
|
|
|
|
} else if n.ID == 0 {
|
|
|
|
t.Fatalf("unexpected id: %d", n.ID)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ensure the server returns an error when creating a duplicate node.
|
2014-12-30 15:50:15 +00:00
|
|
|
func TestServer_CreateDatabase_ErrDataNodeExists(t *testing.T) {
|
2014-12-29 23:12:51 +00:00
|
|
|
s := OpenServer(NewMessagingClient())
|
|
|
|
defer s.Close()
|
|
|
|
|
|
|
|
// Create a node with the same URL twice.
|
|
|
|
u, _ := url.Parse("http://localhost:80000")
|
2014-12-30 15:50:15 +00:00
|
|
|
if err := s.CreateDataNode(u); err != nil {
|
2014-12-29 23:12:51 +00:00
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2014-12-30 15:50:15 +00:00
|
|
|
if err := s.CreateDataNode(u); err != influxdb.ErrDataNodeExists {
|
2014-12-29 23:12:51 +00:00
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ensure the server can delete a node.
|
2014-12-30 15:50:15 +00:00
|
|
|
func TestServer_DeleteDataNode(t *testing.T) {
|
2014-12-29 23:12:51 +00:00
|
|
|
s := OpenServer(NewMessagingClient())
|
|
|
|
defer s.Close()
|
|
|
|
|
2014-12-30 15:50:15 +00:00
|
|
|
// Create a data node and verify it exists.
|
2014-12-29 23:12:51 +00:00
|
|
|
u, _ := url.Parse("http://localhost:80000")
|
2014-12-30 15:50:15 +00:00
|
|
|
if err := s.CreateDataNode(u); err != nil {
|
2014-12-29 23:12:51 +00:00
|
|
|
t.Fatal(err)
|
2014-12-30 15:50:15 +00:00
|
|
|
} else if s.DataNodeByURL(u) == nil {
|
|
|
|
t.Fatalf("data node not actually created")
|
2014-12-29 23:12:51 +00:00
|
|
|
}
|
|
|
|
s.Restart()
|
|
|
|
|
|
|
|
// Drop the node and verify that it's gone.
|
2014-12-30 15:50:15 +00:00
|
|
|
n := s.DataNodeByURL(u)
|
|
|
|
if err := s.DeleteDataNode(n.ID); err != nil {
|
2014-12-29 23:12:51 +00:00
|
|
|
t.Fatal(err)
|
2014-12-30 15:50:15 +00:00
|
|
|
} else if s.DataNode(n.ID) != nil {
|
|
|
|
t.Fatalf("data node not actually dropped")
|
2014-12-29 23:12:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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)
|
|
|
|
}
|
2014-11-05 05:32:17 +00:00
|
|
|
s.Restart()
|
2014-10-24 05:38:03 +00:00
|
|
|
|
|
|
|
// Verify that the database exists.
|
2014-12-23 06:18:05 +00:00
|
|
|
if !s.DatabaseExists("foo") {
|
2014-10-24 05:38:03 +00:00
|
|
|
t.Fatalf("database not found")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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)
|
2014-12-23 06:18:05 +00:00
|
|
|
} else if !s.DatabaseExists("foo") {
|
2014-10-24 23:45:02 +00:00
|
|
|
t.Fatalf("database not actually created")
|
|
|
|
}
|
2014-11-05 05:32:17 +00:00
|
|
|
s.Restart()
|
2014-10-24 23:45:02 +00:00
|
|
|
|
|
|
|
// Drop the "foo" database and verify that it's gone.
|
|
|
|
if err := s.DeleteDatabase("foo"); err != nil {
|
|
|
|
t.Fatal(err)
|
2014-12-23 06:18:05 +00:00
|
|
|
} else if s.DatabaseExists("foo") {
|
2014-10-24 23:45:02 +00:00
|
|
|
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")
|
2014-11-05 05:32:17 +00:00
|
|
|
s.Restart()
|
2014-10-28 00:16:03 +00:00
|
|
|
|
|
|
|
// Return the databases.
|
|
|
|
if a := s.Databases(); len(a) != 2 {
|
|
|
|
t.Fatalf("unexpected db count: %d", len(a))
|
2014-12-23 06:18:05 +00:00
|
|
|
} else if a[0] != "bar" {
|
|
|
|
t.Fatalf("unexpected db(0): %s", a[0])
|
|
|
|
} else if a[1] != "foo" {
|
|
|
|
t.Fatalf("unexpected db(1): %s", a[1])
|
2014-10-28 00:16:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-23 06:18:05 +00:00
|
|
|
// Ensure the server can create a new user.
|
|
|
|
func TestServer_CreateUser(t *testing.T) {
|
2014-10-28 23:54:49 +00:00
|
|
|
s := OpenServer(NewMessagingClient())
|
|
|
|
defer s.Close()
|
|
|
|
|
2014-12-23 06:18:05 +00:00
|
|
|
// Create a user.
|
|
|
|
if err := s.CreateUser("susy", "pass", true); err != nil {
|
2014-10-28 23:54:49 +00:00
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2014-11-05 05:32:17 +00:00
|
|
|
s.Restart()
|
2014-10-28 23:54:49 +00:00
|
|
|
|
2014-12-23 06:18:05 +00:00
|
|
|
// Verify that the user exists.
|
|
|
|
if u := s.User("susy"); u == nil {
|
|
|
|
t.Fatalf("user not found")
|
2014-10-28 23:54:49 +00:00
|
|
|
} else if u.Name != "susy" {
|
|
|
|
t.Fatalf("username mismatch: %v", u.Name)
|
2014-12-23 06:18:05 +00:00
|
|
|
} else if !u.Admin {
|
|
|
|
t.Fatalf("admin mismatch: %v", u.Admin)
|
2014-10-28 23:54:49 +00:00
|
|
|
} else if bcrypt.CompareHashAndPassword([]byte(u.Hash), []byte("pass")) != nil {
|
|
|
|
t.Fatal("invalid password")
|
|
|
|
}
|
2015-01-05 06:23:18 +00:00
|
|
|
|
|
|
|
// Verify that the authenticated user exists.
|
2015-01-06 17:19:31 +00:00
|
|
|
u, err := s.Authenticate("susy", "pass")
|
2015-01-05 06:23:18 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("error fetching authenticated user")
|
|
|
|
} else if u.Name != "susy" {
|
|
|
|
t.Fatalf("username mismatch: %v", u.Name)
|
|
|
|
} else if !u.Admin {
|
|
|
|
t.Fatalf("admin mismatch: %v", u.Admin)
|
|
|
|
} else if bcrypt.CompareHashAndPassword([]byte(u.Hash), []byte("pass")) != nil {
|
|
|
|
t.Fatal("invalid password")
|
|
|
|
}
|
|
|
|
|
2014-10-28 23:54:49 +00:00
|
|
|
}
|
|
|
|
|
2015-01-02 21:19:32 +00:00
|
|
|
// Ensure the server correctly detects when there is an admin user.
|
|
|
|
func TestServer_AdminUserExists(t *testing.T) {
|
|
|
|
s := OpenServer(NewMessagingClient())
|
|
|
|
defer s.Close()
|
|
|
|
|
|
|
|
// A server should start up without any admin user.
|
|
|
|
if s.AdminUserExists() {
|
|
|
|
t.Fatalf("admin user unexpectedly exists at start-up")
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create a non-admin user and verify Server agrees there is no admin user.
|
|
|
|
if err := s.CreateUser("bert", "pass", false); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
s.Restart()
|
|
|
|
if s.AdminUserExists() {
|
|
|
|
t.Fatalf("admin user unexpectedly exists")
|
|
|
|
}
|
|
|
|
|
|
|
|
// Next, create an admin user, and ensure the Server agrees there is an admin user.
|
|
|
|
if err := s.CreateUser("ernie", "pass", true); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
s.Restart()
|
|
|
|
if !s.AdminUserExists() {
|
|
|
|
t.Fatalf("admin user does not exist")
|
|
|
|
}
|
2014-10-28 23:54:49 +00:00
|
|
|
}
|
|
|
|
|
2014-12-23 06:18:05 +00:00
|
|
|
// Ensure the server returns an error when creating an user without a name.
|
|
|
|
func TestServer_CreateUser_ErrUsernameRequired(t *testing.T) {
|
2014-10-29 00:43:03 +00:00
|
|
|
s := OpenServer(NewMessagingClient())
|
|
|
|
defer s.Close()
|
2014-12-23 06:18:05 +00:00
|
|
|
if err := s.CreateUser("", "pass", false); err != influxdb.ErrUsernameRequired {
|
2014-10-29 00:43:03 +00:00
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-23 06:18:05 +00:00
|
|
|
// Ensure the server returns an error when creating a duplicate user.
|
|
|
|
func TestServer_CreateUser_ErrUserExists(t *testing.T) {
|
2014-10-29 00:43:03 +00:00
|
|
|
s := OpenServer(NewMessagingClient())
|
|
|
|
defer s.Close()
|
2014-12-23 06:18:05 +00:00
|
|
|
if err := s.CreateUser("susy", "pass", false); err != nil {
|
2014-10-29 00:43:03 +00:00
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2014-12-23 06:18:05 +00:00
|
|
|
if err := s.CreateUser("susy", "pass", false); err != influxdb.ErrUserExists {
|
2014-10-29 00:43:03 +00:00
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-23 06:18:05 +00:00
|
|
|
// Ensure the server can delete an existing user.
|
|
|
|
func TestServer_DeleteUser(t *testing.T) {
|
2014-10-29 00:43:03 +00:00
|
|
|
s := OpenServer(NewMessagingClient())
|
|
|
|
defer s.Close()
|
|
|
|
|
2014-12-23 06:18:05 +00:00
|
|
|
// Create a user.
|
|
|
|
if err := s.CreateUser("susy", "pass", false); err != nil {
|
2014-10-29 00:43:03 +00:00
|
|
|
t.Fatal(err)
|
2014-12-23 06:18:05 +00:00
|
|
|
} else if s.User("susy") == nil {
|
|
|
|
t.Fatalf("user not created")
|
2014-10-29 00:43:03 +00:00
|
|
|
}
|
|
|
|
|
2014-12-23 06:18:05 +00:00
|
|
|
// Delete the user.
|
|
|
|
if err := s.DeleteUser("susy"); err != nil {
|
2014-10-29 00:43:03 +00:00
|
|
|
t.Fatal(err)
|
2014-12-23 06:18:05 +00:00
|
|
|
} else if s.User("susy") != nil {
|
|
|
|
t.Fatalf("user not actually deleted")
|
2014-10-29 00:43:03 +00:00
|
|
|
}
|
2014-11-05 05:32:17 +00:00
|
|
|
s.Restart()
|
|
|
|
|
2014-12-23 06:18:05 +00:00
|
|
|
if s.User("susy") != nil {
|
|
|
|
t.Fatalf("user not actually deleted after restart")
|
2014-11-05 05:32:17 +00:00
|
|
|
}
|
2014-10-29 00:43:03 +00:00
|
|
|
}
|
|
|
|
|
2014-12-23 06:18:05 +00:00
|
|
|
// Ensure the server can return a list of all users.
|
|
|
|
func TestServer_Users(t *testing.T) {
|
2014-10-29 01:34:12 +00:00
|
|
|
s := OpenServer(NewMessagingClient())
|
|
|
|
defer s.Close()
|
|
|
|
|
2015-01-05 06:11:37 +00:00
|
|
|
// Create some users.
|
2014-12-23 06:18:05 +00:00
|
|
|
s.CreateUser("susy", "pass", false)
|
|
|
|
s.CreateUser("john", "pass", false)
|
2014-11-05 05:32:17 +00:00
|
|
|
s.Restart()
|
2014-10-29 01:34:12 +00:00
|
|
|
|
2015-01-05 06:11:37 +00:00
|
|
|
// Return the users.
|
2014-12-23 06:18:05 +00:00
|
|
|
if a := s.Users(); len(a) != 2 {
|
|
|
|
t.Fatalf("unexpected user count: %d", len(a))
|
2014-10-29 01:34:12 +00:00
|
|
|
} else if a[0].Name != "john" {
|
2014-12-23 06:18:05 +00:00
|
|
|
t.Fatalf("unexpected user(0): %s", a[0].Name)
|
2014-10-29 01:34:12 +00:00
|
|
|
} else if a[1].Name != "susy" {
|
2014-12-23 06:18:05 +00:00
|
|
|
t.Fatalf("unexpected user(1): %s", a[1].Name)
|
2014-10-29 01:34:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-05 06:23:18 +00:00
|
|
|
// Ensure the server does not return non-existent users
|
|
|
|
func TestServer_NonExistingUsers(t *testing.T) {
|
|
|
|
s := OpenServer(NewMessagingClient())
|
|
|
|
defer s.Close()
|
|
|
|
|
|
|
|
// Create some users.
|
|
|
|
s.CreateUser("susy", "pass", false)
|
|
|
|
s.CreateUser("john", "pass2", false)
|
|
|
|
s.Restart()
|
|
|
|
|
|
|
|
// Ask for users that should not be returned.
|
|
|
|
u := s.User("bob")
|
|
|
|
if u != nil {
|
|
|
|
t.Fatalf("unexpected user found")
|
|
|
|
}
|
2015-01-06 17:19:31 +00:00
|
|
|
u, err := s.Authenticate("susy", "wrong_password")
|
2015-01-05 06:23:18 +00:00
|
|
|
if err == nil {
|
|
|
|
t.Fatalf("unexpected authenticated user found")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-23 06:18:05 +00:00
|
|
|
// Ensure the database can create a new retention policy.
|
|
|
|
func TestServer_CreateRetentionPolicy(t *testing.T) {
|
|
|
|
s := OpenServer(NewMessagingClient())
|
|
|
|
defer s.Close()
|
|
|
|
|
|
|
|
// Create a database.
|
|
|
|
if err := s.CreateDatabase("foo"); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create a retention policy on the database.
|
|
|
|
rp := &influxdb.RetentionPolicy{
|
|
|
|
Name: "bar",
|
|
|
|
Duration: time.Hour,
|
|
|
|
ReplicaN: 2,
|
|
|
|
}
|
|
|
|
if err := s.CreateRetentionPolicy("foo", rp); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
s.Restart()
|
|
|
|
|
|
|
|
// Verify that the policy exists.
|
|
|
|
if o, err := s.RetentionPolicy("foo", "bar"); err != nil {
|
|
|
|
t.Fatalf("unexpected error: %s", err)
|
|
|
|
} else if o == nil {
|
|
|
|
t.Fatalf("retention policy not found")
|
|
|
|
} else if !reflect.DeepEqual(rp, o) {
|
|
|
|
t.Fatalf("retention policy mismatch: %#v", o)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ensure the server returns an error when creating a retention policy with an invalid db.
|
|
|
|
func TestServer_CreateRetentionPolicy_ErrDatabaseNotFound(t *testing.T) {
|
|
|
|
s := OpenServer(NewMessagingClient())
|
|
|
|
defer s.Close()
|
|
|
|
if err := s.CreateRetentionPolicy("foo", &influxdb.RetentionPolicy{Name: "bar"}); err != influxdb.ErrDatabaseNotFound {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ensure the server returns an error when creating a retention policy without a name.
|
|
|
|
func TestServer_CreateRetentionPolicy_ErrRetentionPolicyNameRequired(t *testing.T) {
|
|
|
|
s := OpenServer(NewMessagingClient())
|
|
|
|
defer s.Close()
|
|
|
|
s.CreateDatabase("foo")
|
|
|
|
if err := s.CreateRetentionPolicy("foo", &influxdb.RetentionPolicy{Name: ""}); err != influxdb.ErrRetentionPolicyNameRequired {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ensure the server returns an error when creating a duplicate retention policy.
|
|
|
|
func TestServer_CreateRetentionPolicy_ErrRetentionPolicyExists(t *testing.T) {
|
|
|
|
s := OpenServer(NewMessagingClient())
|
|
|
|
defer s.Close()
|
|
|
|
s.CreateDatabase("foo")
|
|
|
|
s.CreateRetentionPolicy("foo", &influxdb.RetentionPolicy{Name: "bar"})
|
|
|
|
if err := s.CreateRetentionPolicy("foo", &influxdb.RetentionPolicy{Name: "bar"}); err != influxdb.ErrRetentionPolicyExists {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ensure the server can delete an existing retention policy.
|
|
|
|
func TestServer_DeleteRetentionPolicy(t *testing.T) {
|
|
|
|
s := OpenServer(NewMessagingClient())
|
|
|
|
defer s.Close()
|
|
|
|
|
|
|
|
// Create a database and retention policy.
|
|
|
|
s.CreateDatabase("foo")
|
|
|
|
if err := s.CreateRetentionPolicy("foo", &influxdb.RetentionPolicy{Name: "bar"}); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
} else if rp, _ := s.RetentionPolicy("foo", "bar"); rp == nil {
|
|
|
|
t.Fatal("retention policy not created")
|
|
|
|
}
|
|
|
|
|
|
|
|
// Remove retention policy from database.
|
|
|
|
if err := s.DeleteRetentionPolicy("foo", "bar"); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
} else if rp, _ := s.RetentionPolicy("foo", "bar"); rp != nil {
|
|
|
|
t.Fatal("retention policy not deleted")
|
|
|
|
}
|
|
|
|
s.Restart()
|
|
|
|
|
|
|
|
if rp, _ := s.RetentionPolicy("foo", "bar"); rp != nil {
|
|
|
|
t.Fatal("retention policy not deleted after restart")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ensure the server returns an error when deleting a retention policy on invalid db.
|
|
|
|
func TestServer_DeleteRetentionPolicy_ErrDatabaseNotFound(t *testing.T) {
|
|
|
|
s := OpenServer(NewMessagingClient())
|
|
|
|
defer s.Close()
|
|
|
|
if err := s.DeleteRetentionPolicy("foo", "bar"); err != influxdb.ErrDatabaseNotFound {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ensure the server returns an error when deleting a retention policy without a name.
|
|
|
|
func TestServer_DeleteRetentionPolicy_ErrRetentionPolicyNameRequired(t *testing.T) {
|
|
|
|
s := OpenServer(NewMessagingClient())
|
|
|
|
defer s.Close()
|
|
|
|
s.CreateDatabase("foo")
|
|
|
|
if err := s.DeleteRetentionPolicy("foo", ""); err != influxdb.ErrRetentionPolicyNameRequired {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ensure the server returns an error when deleting a non-existent retention policy.
|
|
|
|
func TestServer_DeleteRetentionPolicy_ErrRetentionPolicyNotFound(t *testing.T) {
|
|
|
|
s := OpenServer(NewMessagingClient())
|
|
|
|
defer s.Close()
|
|
|
|
s.CreateDatabase("foo")
|
|
|
|
if err := s.DeleteRetentionPolicy("foo", "no_such_policy"); err != influxdb.ErrRetentionPolicyNotFound {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ensure the server can set the default retention policy
|
|
|
|
func TestServer_SetDefaultRetentionPolicy(t *testing.T) {
|
|
|
|
s := OpenServer(NewMessagingClient())
|
|
|
|
defer s.Close()
|
|
|
|
s.CreateDatabase("foo")
|
|
|
|
|
|
|
|
rp := &influxdb.RetentionPolicy{Name: "bar"}
|
|
|
|
if err := s.CreateRetentionPolicy("foo", rp); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
} else if rp, _ := s.RetentionPolicy("foo", "bar"); rp == nil {
|
|
|
|
t.Fatal("retention policy not created")
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set bar as default
|
|
|
|
if err := s.SetDefaultRetentionPolicy("foo", "bar"); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if o, _ := s.DefaultRetentionPolicy("foo"); o == nil {
|
|
|
|
t.Fatal("default policy not set")
|
|
|
|
} else if !reflect.DeepEqual(rp, o) {
|
|
|
|
t.Fatalf("retention policy mismatch: %#v", o)
|
|
|
|
}
|
|
|
|
|
|
|
|
s.Restart()
|
|
|
|
|
|
|
|
if o, _ := s.DefaultRetentionPolicy("foo"); o == nil {
|
|
|
|
t.Fatal("default policy not kept after restart")
|
|
|
|
} else if !reflect.DeepEqual(rp, o) {
|
|
|
|
t.Fatalf("retention policy mismatch after restart: %#v", o)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ensure the server returns an error when setting the deafult retention policy to a non-existant one.
|
|
|
|
func TestServer_SetDefaultRetentionPolicy_ErrRetentionPolicyNotFound(t *testing.T) {
|
|
|
|
s := OpenServer(NewMessagingClient())
|
|
|
|
defer s.Close()
|
|
|
|
s.CreateDatabase("foo")
|
|
|
|
if err := s.SetDefaultRetentionPolicy("foo", "no_such_policy"); err != influxdb.ErrRetentionPolicyNotFound {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ensure the database can write data to the database.
|
|
|
|
func TestServer_WriteSeries(t *testing.T) {
|
2015-01-10 15:48:50 +00:00
|
|
|
c := NewMessagingClient()
|
|
|
|
s := OpenServer(c)
|
2014-12-23 06:18:05 +00:00
|
|
|
defer s.Close()
|
|
|
|
s.CreateDatabase("foo")
|
2015-01-12 20:10:26 +00:00
|
|
|
s.CreateRetentionPolicy("foo", &influxdb.RetentionPolicy{Name: "mypolicy", Duration: 1 * time.Hour})
|
2014-12-23 06:18:05 +00:00
|
|
|
s.CreateUser("susy", "pass", false)
|
|
|
|
|
2015-01-10 15:48:50 +00:00
|
|
|
// Check if a topic is being subscribed to.
|
|
|
|
var subscribed bool
|
|
|
|
c.SubscribeFunc = func(replicaID, topicID uint64) error {
|
|
|
|
subscribed = true
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2014-12-23 06:18:05 +00:00
|
|
|
// Write series with one point to the database.
|
|
|
|
tags := map[string]string{"host": "servera.influx.com", "region": "uswest"}
|
2015-01-15 05:21:55 +00:00
|
|
|
index, err := s.WriteSeries("foo", "mypolicy", []influxdb.Point{influxdb.Point{Name: "cpu_load", Tags: tags, Timestamp: mustParseTime("2000-01-01T00:00:00Z"), Values: map[string]interface{}{"value": float64(23.2)}}})
|
2015-01-13 17:16:43 +00:00
|
|
|
if err != nil {
|
2015-01-10 20:22:57 +00:00
|
|
|
t.Fatal(err)
|
2015-01-13 17:16:43 +00:00
|
|
|
} else if err = s.Sync(index); err != nil {
|
|
|
|
t.Fatalf("sync error: %s", err)
|
2015-01-10 20:22:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Write another point 10 seconds later so it goes through "raw series".
|
2015-01-15 05:21:55 +00:00
|
|
|
index, err = s.WriteSeries("foo", "mypolicy", []influxdb.Point{influxdb.Point{Name: "cpu_load", Tags: tags, Timestamp: mustParseTime("2000-01-01T00:00:10Z"), Values: map[string]interface{}{"value": float64(100)}}})
|
2015-01-13 17:16:43 +00:00
|
|
|
if err != nil {
|
2014-12-23 06:18:05 +00:00
|
|
|
t.Fatal(err)
|
2015-01-13 17:16:43 +00:00
|
|
|
} else if err = s.Sync(index); err != nil {
|
|
|
|
t.Fatalf("sync error: %s", err)
|
2014-12-23 06:18:05 +00:00
|
|
|
}
|
|
|
|
|
2015-01-10 15:48:50 +00:00
|
|
|
// Verify a subscription was made.
|
|
|
|
if !subscribed {
|
|
|
|
t.Fatal("expected subscription")
|
|
|
|
}
|
2014-12-24 00:01:06 +00:00
|
|
|
|
2015-01-13 17:16:43 +00:00
|
|
|
// Retrieve first series data point.
|
2015-01-12 20:10:26 +00:00
|
|
|
if v, err := s.ReadSeries("foo", "mypolicy", "cpu_load", tags, mustParseTime("2000-01-01T00:00:00Z")); err != nil {
|
2015-01-10 15:48:50 +00:00
|
|
|
t.Fatal(err)
|
2015-01-14 23:44:09 +00:00
|
|
|
} else if !reflect.DeepEqual(v, map[string]interface{}{"value": float64(23.2)}) {
|
2015-01-10 15:48:50 +00:00
|
|
|
t.Fatalf("values mismatch: %#v", v)
|
|
|
|
}
|
2015-01-13 17:16:43 +00:00
|
|
|
|
|
|
|
// Retrieve second series data point.
|
|
|
|
if v, err := s.ReadSeries("foo", "mypolicy", "cpu_load", tags, mustParseTime("2000-01-01T00:00:10Z")); err != nil {
|
|
|
|
t.Fatal(err)
|
2015-01-14 23:44:09 +00:00
|
|
|
} else if mustMarshalJSON(v) != mustMarshalJSON(map[string]interface{}{"value": float64(100)}) {
|
2015-01-10 15:48:50 +00:00
|
|
|
t.Fatalf("values mismatch: %#v", v)
|
2015-01-13 17:16:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Retrieve non-existent series data point.
|
|
|
|
if v, err := s.ReadSeries("foo", "mypolicy", "cpu_load", tags, mustParseTime("2000-01-01T00:01:00Z")); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
} else if v != nil {
|
|
|
|
t.Fatalf("expected nil values: %#v", v)
|
|
|
|
}
|
2014-12-23 06:18:05 +00:00
|
|
|
}
|
|
|
|
|
2015-01-14 23:44:09 +00:00
|
|
|
// Ensure the server can execute a query and return the data correctly.
|
|
|
|
func TestServer_ExecuteQuery(t *testing.T) {
|
|
|
|
s := OpenServer(NewMessagingClient())
|
|
|
|
defer s.Close()
|
|
|
|
s.CreateDatabase("foo")
|
|
|
|
s.CreateRetentionPolicy("foo", &influxdb.RetentionPolicy{Name: "raw", Duration: 1 * time.Hour})
|
|
|
|
s.SetDefaultRetentionPolicy("foo", "raw")
|
|
|
|
s.CreateUser("susy", "pass", false)
|
|
|
|
|
|
|
|
// Write series with one point to the database.
|
2015-01-15 05:21:55 +00:00
|
|
|
s.MustWriteSeries("foo", "raw", []influxdb.Point{{Name: "cpu", Tags: map[string]string{"region": "us-east"}, Timestamp: mustParseTime("2000-01-01T00:00:00Z"), Values: map[string]interface{}{"value": float64(20)}}})
|
|
|
|
s.MustWriteSeries("foo", "raw", []influxdb.Point{{Name: "cpu", Tags: map[string]string{"region": "us-east"}, Timestamp: mustParseTime("2000-01-01T00:00:10Z"), Values: map[string]interface{}{"value": float64(30)}}})
|
|
|
|
s.MustWriteSeries("foo", "raw", []influxdb.Point{{Name: "cpu", Tags: map[string]string{"region": "us-west"}, Timestamp: mustParseTime("2000-01-01T00:00:00Z"), Values: map[string]interface{}{"value": float64(100)}}})
|
2015-01-14 23:44:09 +00:00
|
|
|
|
|
|
|
// Select data from the server.
|
2015-01-15 05:21:55 +00:00
|
|
|
results := s.ExecuteQuery(MustParseQuery("SELECT sum(value) FROM cpu"), "foo", nil)
|
2015-01-14 23:44:09 +00:00
|
|
|
if len(results) != 1 {
|
|
|
|
t.Fatalf("unexpected result count: %d", len(results))
|
|
|
|
}
|
|
|
|
if res := results[0]; res.Err != nil {
|
|
|
|
t.Fatalf("unexpected error: %s", res.Err)
|
|
|
|
} else if len(res.Rows) != 1 {
|
|
|
|
t.Fatalf("unexpected row count: %s", len(res.Rows))
|
|
|
|
} else if s := mustMarshalJSON(res); s != `{"rows":[{"name":"cpu","columns":["time","sum"],"values":[[0,150]]}]}` {
|
|
|
|
t.Fatalf("unexpected row(0): %s", s)
|
|
|
|
}
|
2014-12-23 06:18:05 +00:00
|
|
|
}
|
|
|
|
|
2015-01-10 15:48:50 +00:00
|
|
|
func TestServer_CreateShardGroupIfNotExist(t *testing.T) {
|
2014-12-23 06:18:05 +00:00
|
|
|
s := OpenServer(NewMessagingClient())
|
|
|
|
defer s.Close()
|
|
|
|
s.CreateDatabase("foo")
|
|
|
|
|
2014-12-23 15:47:32 +00:00
|
|
|
if err := s.CreateRetentionPolicy("foo", &influxdb.RetentionPolicy{Name: "bar"}); err != nil {
|
2014-12-23 06:18:05 +00:00
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2015-01-10 15:48:50 +00:00
|
|
|
if err := s.CreateShardGroupIfNotExists("foo", "bar", time.Time{}); err != nil {
|
2014-12-23 06:18:05 +00:00
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2015-01-10 15:48:50 +00:00
|
|
|
if a, err := s.ShardGroups("foo"); err != nil {
|
2014-12-23 15:47:32 +00:00
|
|
|
t.Fatal(err)
|
2015-01-10 15:48:50 +00:00
|
|
|
} else if len(a) != 1 {
|
|
|
|
t.Fatalf("expected 1 shard group but found %d", len(a))
|
2014-12-23 06:18:05 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestServer_Measurements(t *testing.T) {
|
|
|
|
s := OpenServer(NewMessagingClient())
|
|
|
|
defer s.Close()
|
|
|
|
s.CreateDatabase("foo")
|
2015-01-12 20:10:26 +00:00
|
|
|
s.CreateRetentionPolicy("foo", &influxdb.RetentionPolicy{Name: "mypolicy", Duration: 1 * time.Hour})
|
2014-12-23 15:47:32 +00:00
|
|
|
s.CreateUser("susy", "pass", false)
|
2014-12-23 06:18:05 +00:00
|
|
|
|
|
|
|
// Write series with one point to the database.
|
|
|
|
timestamp := mustParseTime("2000-01-01T00:00:00Z")
|
|
|
|
|
|
|
|
tags := map[string]string{"host": "servera.influx.com", "region": "uswest"}
|
|
|
|
values := map[string]interface{}{"value": 23.2}
|
|
|
|
|
2015-01-13 23:26:14 +00:00
|
|
|
index, err := s.WriteSeries("foo", "mypolicy", []influxdb.Point{influxdb.Point{Name: "cpu_load", Tags: tags, Timestamp: timestamp, Values: values}})
|
2015-01-13 17:16:43 +00:00
|
|
|
if err != nil {
|
2014-12-23 06:18:05 +00:00
|
|
|
t.Fatal(err)
|
2015-01-13 17:16:43 +00:00
|
|
|
} else if err = s.Sync(index); err != nil {
|
2015-01-13 15:00:30 +00:00
|
|
|
t.Fatalf("sync error: %s", err)
|
2014-12-23 06:18:05 +00:00
|
|
|
}
|
|
|
|
|
2014-12-30 22:50:55 +00:00
|
|
|
expectedMeasurementNames := []string{"cpu_load"}
|
2014-12-30 21:45:58 +00:00
|
|
|
expectedSeriesIDs := influxdb.SeriesIDs([]uint32{uint32(1)})
|
|
|
|
names := s.MeasurementNames("foo")
|
|
|
|
if !reflect.DeepEqual(names, expectedMeasurementNames) {
|
|
|
|
t.Fatalf("Mesurements not the same:\n exp: %s\n got: %s", expectedMeasurementNames, names)
|
|
|
|
}
|
|
|
|
ids := s.MeasurementSeriesIDs("foo", "foo")
|
|
|
|
if !ids.Equals(expectedSeriesIDs) {
|
2015-01-11 23:14:22 +00:00
|
|
|
t.Fatalf("Series IDs not the same:\n exp: %v\n got: %v", expectedSeriesIDs, ids)
|
2014-12-23 06:18:05 +00:00
|
|
|
}
|
2014-12-24 04:46:54 +00:00
|
|
|
|
|
|
|
s.Restart()
|
2014-12-30 21:45:58 +00:00
|
|
|
|
|
|
|
names = s.MeasurementNames("foo")
|
|
|
|
if !reflect.DeepEqual(names, expectedMeasurementNames) {
|
|
|
|
t.Fatalf("Mesurements not the same:\n exp: %s\n got: %s", expectedMeasurementNames, names)
|
|
|
|
}
|
|
|
|
ids = s.MeasurementSeriesIDs("foo", "foo")
|
|
|
|
if !ids.Equals(expectedSeriesIDs) {
|
2015-01-11 23:14:22 +00:00
|
|
|
t.Fatalf("Series IDs not the same:\n exp: %v\n got: %v", expectedSeriesIDs, ids)
|
2014-12-23 06:18:05 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-24 04:46:54 +00:00
|
|
|
func mustMarshalJSON(v interface{}) string {
|
|
|
|
b, err := json.Marshal(v)
|
|
|
|
if err != nil {
|
|
|
|
panic("marshal: " + err.Error())
|
2014-12-23 06:18:05 +00:00
|
|
|
}
|
2014-12-24 04:46:54 +00:00
|
|
|
return string(b)
|
|
|
|
}
|
|
|
|
|
|
|
|
func measurementsEqual(l influxdb.Measurements, r influxdb.Measurements) bool {
|
|
|
|
if mustMarshalJSON(l) == mustMarshalJSON(r) {
|
|
|
|
return true
|
2014-12-23 06:18:05 +00:00
|
|
|
}
|
2014-12-24 04:46:54 +00:00
|
|
|
return false
|
2014-12-23 06:18:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestServer_SeriesByTagNames(t *testing.T) { t.Skip("pending") }
|
|
|
|
func TestServer_SeriesByTagValues(t *testing.T) { t.Skip("pending") }
|
|
|
|
func TestDatabase_TagNames(t *testing.T) { t.Skip("pending") }
|
|
|
|
func TestServer_TagNamesBySeries(t *testing.T) { t.Skip("pending") }
|
|
|
|
func TestServer_TagValues(t *testing.T) { t.Skip("pending") }
|
|
|
|
func TestServer_TagValuesBySeries(t *testing.T) { t.Skip("pending") }
|
|
|
|
|
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.
|
2014-12-30 22:46:50 +00:00
|
|
|
func NewServer() *Server {
|
|
|
|
return &Server{influxdb.NewServer()}
|
2014-10-22 05:32:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// OpenServer returns a new, open test server instance.
|
|
|
|
func OpenServer(client influxdb.MessagingClient) *Server {
|
2015-01-10 15:48:50 +00:00
|
|
|
s := OpenUninitializedServer(client)
|
|
|
|
if err := s.Initialize(&url.URL{Host: "127.0.0.1:8080"}); err != nil {
|
|
|
|
panic(err.Error())
|
|
|
|
}
|
|
|
|
return s
|
|
|
|
}
|
|
|
|
|
|
|
|
// OpenUninitializedServer returns a new, uninitialized, open test server instance.
|
|
|
|
func OpenUninitializedServer(client influxdb.MessagingClient) *Server {
|
2014-12-30 22:46:50 +00:00
|
|
|
s := NewServer()
|
2014-10-22 05:32:19 +00:00
|
|
|
if err := s.Open(tempfile()); err != nil {
|
|
|
|
panic(err.Error())
|
|
|
|
}
|
2014-12-30 22:46:50 +00:00
|
|
|
if err := s.SetClient(client); err != nil {
|
|
|
|
panic(err.Error())
|
|
|
|
}
|
2014-10-22 05:32:19 +00:00
|
|
|
return s
|
|
|
|
}
|
|
|
|
|
2014-11-05 05:32:17 +00:00
|
|
|
// Restart stops and restarts the server.
|
|
|
|
func (s *Server) Restart() {
|
2014-12-30 22:46:50 +00:00
|
|
|
path, client := s.Path(), s.Client()
|
|
|
|
|
|
|
|
// Stop the server.
|
2014-11-05 05:32:17 +00:00
|
|
|
if err := s.Server.Close(); err != nil {
|
|
|
|
panic("close: " + err.Error())
|
|
|
|
}
|
2014-12-30 22:46:50 +00:00
|
|
|
|
|
|
|
// Open and reset the client.
|
2014-11-05 05:32:17 +00:00
|
|
|
if err := s.Server.Open(path); err != nil {
|
|
|
|
panic("open: " + err.Error())
|
|
|
|
}
|
2014-12-30 22:46:50 +00:00
|
|
|
if err := s.Server.SetClient(client); err != nil {
|
|
|
|
panic("client: " + err.Error())
|
|
|
|
}
|
2014-11-05 05:32:17 +00:00
|
|
|
}
|
|
|
|
|
2014-10-22 05:32:19 +00:00
|
|
|
// Close shuts down the server and removes all temporary files.
|
|
|
|
func (s *Server) Close() {
|
|
|
|
defer os.RemoveAll(s.Path())
|
|
|
|
s.Server.Close()
|
|
|
|
}
|
|
|
|
|
2015-01-14 23:44:09 +00:00
|
|
|
// MustWriteSeries writes series data and waits for the data to be applied.
|
|
|
|
// Returns the messaging index for the write.
|
2015-01-15 05:21:55 +00:00
|
|
|
func (s *Server) MustWriteSeries(database, retentionPolicy string, points []influxdb.Point) uint64 {
|
|
|
|
index, err := s.WriteSeries(database, retentionPolicy, points)
|
2015-01-14 23:44:09 +00:00
|
|
|
if err != nil {
|
|
|
|
panic(err.Error())
|
|
|
|
} else if err = s.Sync(index); err != nil {
|
|
|
|
panic("sync error: " + err.Error())
|
|
|
|
}
|
|
|
|
return index
|
|
|
|
}
|
|
|
|
|
2014-10-22 05:32:19 +00:00
|
|
|
// 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
|
|
|
|
|
2015-01-10 15:48:50 +00:00
|
|
|
PublishFunc func(*messaging.Message) (uint64, error)
|
|
|
|
CreateReplicaFunc func(replicaID uint64) error
|
|
|
|
DeleteReplicaFunc func(replicaID uint64) error
|
|
|
|
SubscribeFunc func(replicaID, topicID uint64) error
|
|
|
|
UnsubscribeFunc func(replicaID, topicID 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
|
2015-01-10 15:48:50 +00:00
|
|
|
c.CreateReplicaFunc = func(replicaID uint64) error { return nil }
|
|
|
|
c.DeleteReplicaFunc = func(replicaID uint64) error { return nil }
|
|
|
|
c.SubscribeFunc = func(replicaID, topicID uint64) error { return nil }
|
|
|
|
c.UnsubscribeFunc = func(replicaID, topicID uint64) error { return nil }
|
2014-10-24 05:38:03 +00:00
|
|
|
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
|
|
|
}
|
|
|
|
|
2015-01-07 00:21:32 +00:00
|
|
|
// Creates a new replica with a given ID on the broker.
|
2015-01-10 15:48:50 +00:00
|
|
|
func (c *MessagingClient) CreateReplica(replicaID uint64) error {
|
|
|
|
return c.CreateReplicaFunc(replicaID)
|
|
|
|
}
|
2015-01-07 00:21:32 +00:00
|
|
|
|
|
|
|
// Deletes an existing replica with a given ID from the broker.
|
2015-01-10 15:48:50 +00:00
|
|
|
func (c *MessagingClient) DeleteReplica(replicaID uint64) error {
|
|
|
|
return c.DeleteReplicaFunc(replicaID)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Subscribe adds a subscription to a replica for a topic on the broker.
|
|
|
|
func (c *MessagingClient) Subscribe(replicaID, topicID uint64) error {
|
|
|
|
return c.SubscribeFunc(replicaID, topicID)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Unsubscribe removes a subscrition from a replica for a topic on the broker.
|
|
|
|
func (c *MessagingClient) Unsubscribe(replicaID, topicID uint64) error {
|
|
|
|
return c.UnsubscribeFunc(replicaID, topicID)
|
|
|
|
}
|
2015-01-07 00:21:32 +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-11-10 02:55:53 +00:00
|
|
|
// mustParseTime parses an IS0-8601 string. Panic on error.
|
|
|
|
func mustParseTime(s string) time.Time {
|
|
|
|
t, err := time.Parse(time.RFC3339, s)
|
|
|
|
if err != nil {
|
|
|
|
panic(err.Error())
|
|
|
|
}
|
|
|
|
return t
|
|
|
|
}
|
|
|
|
|
2015-01-14 23:44:09 +00:00
|
|
|
// MustParseQuery parses an InfluxQL query. Panic on error.
|
|
|
|
func MustParseQuery(s string) *influxql.Query {
|
|
|
|
q, err := influxql.NewParser(strings.NewReader(s)).ParseQuery()
|
|
|
|
if err != nil {
|
|
|
|
panic(err.Error())
|
|
|
|
}
|
|
|
|
return q
|
|
|
|
}
|
|
|
|
|
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...) }
|