697 lines
20 KiB
Go
697 lines
20 KiB
Go
package influxdb_test
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/base64"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"net/url"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/influxdb/influxdb"
|
|
)
|
|
|
|
func init() {
|
|
influxdb.BcryptCost = 4
|
|
}
|
|
|
|
func TestHandler_Databases(t *testing.T) {
|
|
srvr := OpenServer(NewMessagingClient())
|
|
srvr.CreateDatabase("foo")
|
|
srvr.CreateDatabase("bar")
|
|
s := NewHTTPServer(srvr)
|
|
defer s.Close()
|
|
|
|
status, body := MustHTTP("GET", s.URL+`/db`, "")
|
|
|
|
if status != http.StatusOK {
|
|
t.Fatalf("unexpected status: %d", status)
|
|
} else if body != `["bar","foo"]` {
|
|
t.Fatalf("unexpected body: %s", body)
|
|
}
|
|
}
|
|
|
|
func TestHandler_CreateDatabase(t *testing.T) {
|
|
srvr := OpenServer(NewMessagingClient())
|
|
s := NewHTTPServer(srvr)
|
|
defer s.Close()
|
|
|
|
status, body := MustHTTP("POST", s.URL+`/db`, `{"name": "foo"}`)
|
|
|
|
if status != http.StatusCreated {
|
|
t.Fatalf("unexpected status: %d", status)
|
|
} else if body != `` {
|
|
t.Fatalf("unexpected body: %s", body)
|
|
}
|
|
}
|
|
|
|
func TestHandler_CreateDatabase_BadRequest_NoName(t *testing.T) {
|
|
srvr := OpenServer(NewMessagingClient())
|
|
s := NewHTTPServer(srvr)
|
|
defer s.Close()
|
|
|
|
status, body := MustHTTP("POST", s.URL+`/db`, `{"BadRequest": 1}`)
|
|
|
|
if status != http.StatusBadRequest {
|
|
t.Fatalf("unexpected status: %d", status)
|
|
} else if body != `database name required` {
|
|
t.Fatalf("unexpected body: %s", body)
|
|
}
|
|
}
|
|
|
|
func TestHandler_CreateDatabase_BadRequest_InvalidJSON(t *testing.T) {
|
|
srvr := OpenServer(NewMessagingClient())
|
|
s := NewHTTPServer(srvr)
|
|
defer s.Close()
|
|
|
|
status, body := MustHTTP("POST", s.URL+`/db`, `"BadRequest": 1`)
|
|
|
|
if status != http.StatusBadRequest {
|
|
t.Fatalf("unexpected status: %d", status)
|
|
} else if body != `json: cannot unmarshal string into Go value of type struct { Name string "json:\"name\"" }` {
|
|
t.Fatalf("unexpected body: %s", body)
|
|
}
|
|
}
|
|
|
|
func TestHandler_CreateDatabase_Conflict(t *testing.T) {
|
|
srvr := OpenServer(NewMessagingClient())
|
|
srvr.CreateDatabase("foo")
|
|
s := NewHTTPServer(srvr)
|
|
defer s.Close()
|
|
|
|
status, body := MustHTTP("POST", s.URL+`/db`, `{"name": "foo"}`)
|
|
|
|
if status != http.StatusConflict {
|
|
t.Fatalf("unexpected status: %d", status)
|
|
} else if body != `database exists` {
|
|
t.Fatalf("unexpected body: %s", body)
|
|
}
|
|
}
|
|
|
|
func TestHandler_DeleteDatabase(t *testing.T) {
|
|
srvr := OpenServer(NewMessagingClient())
|
|
srvr.CreateDatabase("foo")
|
|
s := NewHTTPServer(srvr)
|
|
defer s.Close()
|
|
|
|
status, body := MustHTTP("DELETE", s.URL+`/db/foo`, "")
|
|
|
|
if status != http.StatusNoContent {
|
|
t.Fatalf("unexpected status: %d", status)
|
|
} else if body != "" {
|
|
t.Fatalf("unexpected body: %s", body)
|
|
}
|
|
}
|
|
|
|
func TestHandler_DeleteDatabase_NotFound(t *testing.T) {
|
|
srvr := OpenServer(NewMessagingClient())
|
|
s := NewHTTPServer(srvr)
|
|
defer s.Close()
|
|
|
|
status, body := MustHTTP("DELETE", s.URL+`/db/foo`, "")
|
|
|
|
if status != http.StatusNotFound {
|
|
t.Fatalf("unexpected status: %d", status)
|
|
} else if body != `database not found` {
|
|
t.Fatalf("unexpected body: %s", body)
|
|
}
|
|
}
|
|
|
|
func TestHandler_RetentionPolicies(t *testing.T) {
|
|
srvr := OpenServer(NewMessagingClient())
|
|
srvr.CreateDatabase("foo")
|
|
srvr.CreateRetentionPolicy("foo", influxdb.NewRetentionPolicy("bar"))
|
|
s := NewHTTPServer(srvr)
|
|
defer s.Close()
|
|
|
|
status, body := MustHTTP("GET", s.URL+`/db/foo/retention_policies`, "")
|
|
|
|
if status != http.StatusOK {
|
|
t.Fatalf("unexpected status: %d", status)
|
|
} else if body != `[{"name":"bar","replicaN":1}]` {
|
|
t.Fatalf("unexpected body: %s", body)
|
|
}
|
|
}
|
|
|
|
func TestHandler_RetentionPolicies_DatabaseNotFound(t *testing.T) {
|
|
srvr := OpenServer(NewMessagingClient())
|
|
s := NewHTTPServer(srvr)
|
|
defer s.Close()
|
|
|
|
status, body := MustHTTP("GET", s.URL+`/db/foo/retention_policies`, "")
|
|
|
|
if status != http.StatusNotFound {
|
|
t.Fatalf("unexpected status: %d", status)
|
|
} else if body != `database not found` {
|
|
t.Fatalf("unexpected body: %s", body)
|
|
}
|
|
}
|
|
|
|
func TestHandler_CreateRetentionPolicy(t *testing.T) {
|
|
srvr := OpenServer(NewMessagingClient())
|
|
srvr.CreateDatabase("foo")
|
|
s := NewHTTPServer(srvr)
|
|
defer s.Close()
|
|
|
|
policy := `{"name": "bar", "duration": 1000000, "replicaN": 1, "splitN": 2}`
|
|
status, body := MustHTTP("POST", s.URL+`/db/foo/retention_policies`, policy)
|
|
|
|
if status != http.StatusCreated {
|
|
t.Fatalf("unexpected status: %d", status)
|
|
} else if body != "" {
|
|
t.Fatalf("unexpected body: %s", body)
|
|
}
|
|
}
|
|
|
|
func TestHandler_CreateRetentionPolicy_DatabaseNotFound(t *testing.T) {
|
|
srvr := OpenServer(NewMessagingClient())
|
|
s := NewHTTPServer(srvr)
|
|
defer s.Close()
|
|
|
|
policy := `{"name": "bar", "duration": 1000000, "replicaN": 1, "splitN": 2}`
|
|
status, body := MustHTTP("POST", s.URL+`/db/foo/retention_policies`, policy)
|
|
|
|
if status != http.StatusNotFound {
|
|
t.Fatalf("unexpected status: %d", status)
|
|
} else if body != "database not found" {
|
|
t.Fatalf("unexpected body: %s", body)
|
|
}
|
|
}
|
|
|
|
func TestHandler_CreateRetentionPolicy_Conflict(t *testing.T) {
|
|
srvr := OpenServer(NewMessagingClient())
|
|
srvr.CreateDatabase("foo")
|
|
s := NewHTTPServer(srvr)
|
|
defer s.Close()
|
|
policy := `{"name": "newName", "duration": 1000000, "replicaN": 1, "splitN": 2}`
|
|
MustHTTP("POST", s.URL+`/db/foo/retention_policies`, policy)
|
|
|
|
status, body := MustHTTP("POST", s.URL+`/db/foo/retention_policies`, policy)
|
|
|
|
if status != http.StatusConflict {
|
|
t.Fatalf("unexpected status: %d", status)
|
|
} else if body != "retention policy exists" {
|
|
t.Fatalf("unexpected body: %s", body)
|
|
}
|
|
}
|
|
|
|
func TestHandler_CreateRetentionPolicy_BadRequest(t *testing.T) {
|
|
srvr := OpenServer(NewMessagingClient())
|
|
srvr.CreateDatabase("foo")
|
|
s := NewHTTPServer(srvr)
|
|
defer s.Close()
|
|
|
|
policy := `{"name": "bar", "duration": "**BAD**", "replicaN": 1, "splitN": 2}`
|
|
status, body := MustHTTP("POST", s.URL+`/db/foo/retention_policies`, policy)
|
|
|
|
if status != http.StatusBadRequest {
|
|
t.Fatalf("unexpected status: %d", status)
|
|
} else if body != "json: cannot unmarshal string into Go value of type time.Duration" {
|
|
t.Fatalf("unexpected body: %s", body)
|
|
}
|
|
}
|
|
|
|
func TestHandler_UpdateRetentionPolicy(t *testing.T) {
|
|
srvr := OpenServer(NewMessagingClient())
|
|
srvr.CreateDatabase("foo")
|
|
srvr.CreateRetentionPolicy("foo", influxdb.NewRetentionPolicy("bar"))
|
|
s := NewHTTPServer(srvr)
|
|
defer s.Close()
|
|
|
|
status, body := MustHTTP("PUT", s.URL+`/db/foo/retention_policies/bar`,
|
|
`{"name": "newName", "duration": 1000000, "replicaN": 1, "splitN": 2}`)
|
|
|
|
// Verify updated policy.
|
|
p, _ := srvr.RetentionPolicy("foo", "newName")
|
|
if status != http.StatusNoContent {
|
|
t.Fatalf("unexpected status: %d", status)
|
|
} else if body != "" {
|
|
t.Fatalf("unexpected body: %s", body)
|
|
} else if p.Name != "newName" {
|
|
t.Fatalf("unexpected policy name: %s", p.Name)
|
|
}
|
|
}
|
|
|
|
func TestHandler_UpdateRetentionPolicy_BadRequest(t *testing.T) {
|
|
srvr := OpenServer(NewMessagingClient())
|
|
srvr.CreateDatabase("foo")
|
|
srvr.CreateRetentionPolicy("foo", influxdb.NewRetentionPolicy("bar"))
|
|
s := NewHTTPServer(srvr)
|
|
defer s.Close()
|
|
|
|
newPolicy := `{"name": "newName", "duration": "BadRequest", "replicaN": 1, "splitN": 2}`
|
|
status, body := MustHTTP("PUT", s.URL+`/db/foo/retention_policies/bar`, newPolicy)
|
|
|
|
// Verify response.
|
|
if status != http.StatusBadRequest {
|
|
t.Fatalf("unexpected status: %d", status)
|
|
} else if body != "json: cannot unmarshal string into Go value of type time.Duration" {
|
|
t.Fatalf("unexpected body: %s", body)
|
|
}
|
|
}
|
|
|
|
func TestHandler_UpdateRetentionPolicy_DatabaseNotFound(t *testing.T) {
|
|
srvr := OpenServer(NewMessagingClient())
|
|
s := NewHTTPServer(srvr)
|
|
defer s.Close()
|
|
|
|
newPolicy := `{"name": "newName", "duration": 1000000, "replicaN": 1, "splitN": 2}`
|
|
status, body := MustHTTP("PUT", s.URL+`/db/foo/retention_policies/bar`, newPolicy)
|
|
|
|
if status != http.StatusNotFound {
|
|
t.Fatalf("unexpected status: %d", status)
|
|
} else if body != "database not found" {
|
|
t.Fatalf("unexpected body: %s", body)
|
|
}
|
|
}
|
|
|
|
func TestHandler_UpdateRetentionPolicy_NotFound(t *testing.T) {
|
|
srvr := OpenServer(NewMessagingClient())
|
|
srvr.CreateDatabase("foo")
|
|
s := NewHTTPServer(srvr)
|
|
defer s.Close()
|
|
|
|
newPolicy := `{"name": "newName", "duration": 1000000, "replicaN": 1, "splitN": 2}`
|
|
status, body := MustHTTP("PUT", s.URL+`/db/foo/retention_policies/bar`, newPolicy)
|
|
|
|
if status != http.StatusNotFound {
|
|
t.Fatalf("unexpected status: %d", status)
|
|
} else if body != "retention policy not found" {
|
|
t.Fatalf("unexpected body: %s", body)
|
|
}
|
|
}
|
|
|
|
func TestHandler_DeleteRetentionPolicy(t *testing.T) {
|
|
srvr := OpenServer(NewMessagingClient())
|
|
srvr.CreateDatabase("foo")
|
|
srvr.CreateRetentionPolicy("foo", influxdb.NewRetentionPolicy("bar"))
|
|
s := NewHTTPServer(srvr)
|
|
defer s.Close()
|
|
|
|
status, body := MustHTTP("DELETE", s.URL+`/db/foo/retention_policies/bar`, "")
|
|
if status != http.StatusNoContent {
|
|
t.Fatalf("unexpected status: %d", status)
|
|
} else if body != "" {
|
|
t.Fatalf("unexpected body: %s", body)
|
|
}
|
|
}
|
|
|
|
func TestHandler_DeleteRetentionPolicy_DatabaseNotFound(t *testing.T) {
|
|
srvr := OpenServer(NewMessagingClient())
|
|
s := NewHTTPServer(srvr)
|
|
defer s.Close()
|
|
|
|
status, body := MustHTTP("DELETE", s.URL+`/db/foo/retention_policies/bar`, "")
|
|
|
|
if status != http.StatusNotFound {
|
|
t.Fatalf("unexpected status: %d", status)
|
|
} else if body != "database not found" {
|
|
t.Fatalf("unexpected body: %s", body)
|
|
}
|
|
}
|
|
|
|
func TestHandler_DeleteRetentionPolicy_NotFound(t *testing.T) {
|
|
srvr := OpenServer(NewMessagingClient())
|
|
srvr.CreateDatabase("foo")
|
|
s := NewHTTPServer(srvr)
|
|
defer s.Close()
|
|
|
|
status, body := MustHTTP("DELETE", s.URL+`/db/foo/retention_policies/bar`, "")
|
|
|
|
if status != http.StatusNotFound {
|
|
t.Fatalf("unexpected status: %d", status)
|
|
} else if body != "retention policy not found" {
|
|
t.Fatalf("unexpected body: %s", body)
|
|
}
|
|
}
|
|
|
|
func TestHandler_Ping(t *testing.T) {
|
|
srvr := OpenServer(NewMessagingClient())
|
|
s := NewHTTPServer(srvr)
|
|
defer s.Close()
|
|
|
|
status, _ := MustHTTP("GET", s.URL+`/ping`, "")
|
|
|
|
if status != http.StatusOK {
|
|
t.Fatalf("unexpected status: %d", status)
|
|
}
|
|
}
|
|
|
|
func TestHandler_Users_NoUsers(t *testing.T) {
|
|
srvr := OpenServer(NewMessagingClient())
|
|
srvr.CreateDatabase("foo")
|
|
s := NewHTTPServer(srvr)
|
|
defer s.Close()
|
|
|
|
status, body := MustHTTP("GET", s.URL+`/users`, "")
|
|
|
|
if status != http.StatusOK {
|
|
t.Fatalf("unexpected status: %d", status)
|
|
} else if body != "[]" {
|
|
t.Fatalf("unexpected body: %s", body)
|
|
}
|
|
}
|
|
|
|
func TestHandler_Users_OneUser(t *testing.T) {
|
|
srvr := OpenServer(NewMessagingClient())
|
|
srvr.CreateUser("jdoe", "1337", true)
|
|
s := NewHTTPServer(srvr)
|
|
defer s.Close()
|
|
|
|
status, body := MustHTTP("GET", s.URL+`/users`, "")
|
|
if status != http.StatusOK {
|
|
t.Fatalf("unexpected status: %d", status)
|
|
} else if body != `[{"name":"jdoe","admin":true}]` {
|
|
t.Fatalf("unexpected body: %s", body)
|
|
}
|
|
}
|
|
|
|
func TestHandler_Users_MultipleUsers(t *testing.T) {
|
|
srvr := OpenServer(NewMessagingClient())
|
|
srvr.CreateUser("jdoe", "1337", false)
|
|
srvr.CreateUser("mclark", "1337", true)
|
|
srvr.CreateUser("csmith", "1337", false)
|
|
s := NewHTTPServer(srvr)
|
|
defer s.Close()
|
|
|
|
status, body := MustHTTP("GET", s.URL+`/users`, "")
|
|
if status != http.StatusOK {
|
|
t.Fatalf("unexpected status: %d", status)
|
|
} else if body != `[{"name":"csmith"},{"name":"jdoe"},{"name":"mclark","admin":true}]` {
|
|
t.Fatalf("unexpected body: %s", body)
|
|
}
|
|
}
|
|
|
|
func TestHandler_CreateUser(t *testing.T) {
|
|
srvr := OpenServer(NewMessagingClient())
|
|
srvr.CreateDatabase("foo")
|
|
s := NewHTTPServer(srvr)
|
|
defer s.Close()
|
|
|
|
status, body := MustHTTP("POST", s.URL+`/users`, `{"name":"jdoe","password":"1337"}`)
|
|
if status != http.StatusCreated {
|
|
t.Fatalf("unexpected status: %d", status)
|
|
} else if body != "" {
|
|
t.Fatalf("unexpected body: %s", body)
|
|
}
|
|
}
|
|
|
|
func TestHandler_CreateUser_BadRequest(t *testing.T) {
|
|
srvr := OpenServer(NewMessagingClient())
|
|
srvr.CreateDatabase("foo")
|
|
s := NewHTTPServer(srvr)
|
|
defer s.Close()
|
|
|
|
status, body := MustHTTP("POST", s.URL+`/users`, `{"name":0xBAD,"password":"1337"}`)
|
|
if status != http.StatusBadRequest {
|
|
t.Fatalf("unexpected status: %d", status)
|
|
} else if body != `invalid character 'x' after object key:value pair` {
|
|
t.Fatalf("unexpected body: %s", body)
|
|
}
|
|
}
|
|
|
|
func TestHandler_CreateUser_InternalServerError(t *testing.T) {
|
|
srvr := OpenServer(NewMessagingClient())
|
|
s := NewHTTPServer(srvr)
|
|
defer s.Close()
|
|
|
|
status, body := MustHTTP("POST", s.URL+`/users`, `{"name":""}`)
|
|
if status != http.StatusInternalServerError {
|
|
t.Fatalf("unexpected status: %d", status)
|
|
} else if body != `username required` {
|
|
t.Fatalf("unexpected body: %s", body)
|
|
}
|
|
}
|
|
|
|
func TestHandler_UpdateUser(t *testing.T) {
|
|
srvr := OpenServer(NewMessagingClient())
|
|
srvr.CreateUser("jdoe", "1337", false)
|
|
s := NewHTTPServer(srvr)
|
|
defer s.Close()
|
|
|
|
// Save original password hash.
|
|
hash := srvr.User("jdoe").Hash
|
|
|
|
// Update user password.
|
|
status, body := MustHTTP("PUT", s.URL+`/users/jdoe`, `{"password": "7331"}`)
|
|
if status != http.StatusNoContent {
|
|
t.Fatalf("unexpected status: %d", status)
|
|
} else if body != `` {
|
|
t.Fatalf("unexpected body: %s", body)
|
|
} else if srvr.User("jdoe").Hash == hash {
|
|
t.Fatalf("expected password hash to change")
|
|
}
|
|
}
|
|
|
|
func TestHandler_UpdateUser_PasswordBadRequest(t *testing.T) {
|
|
srvr := OpenServer(NewMessagingClient())
|
|
srvr.CreateUser("jdoe", "1337", false)
|
|
s := NewHTTPServer(srvr)
|
|
defer s.Close()
|
|
|
|
status, body := MustHTTP("PUT", s.URL+`/users/jdoe`, `{"password": 10}`)
|
|
if status != http.StatusBadRequest {
|
|
t.Fatalf("unexpected status: %d", status)
|
|
} else if body != `json: cannot unmarshal number into Go value of type string` {
|
|
t.Fatalf("unexpected body: %s", body)
|
|
}
|
|
}
|
|
|
|
func TestHandler_DeleteUser(t *testing.T) {
|
|
srvr := OpenServer(NewMessagingClient())
|
|
srvr.CreateUser("jdoe", "1337", false)
|
|
s := NewHTTPServer(srvr)
|
|
defer s.Close()
|
|
|
|
status, body := MustHTTP("DELETE", s.URL+`/users/jdoe`, "")
|
|
if status != http.StatusNoContent {
|
|
t.Fatalf("unexpected status: %d", status)
|
|
} else if body != `` {
|
|
t.Fatalf("unexpected body: %s", body)
|
|
}
|
|
}
|
|
|
|
func TestHandler_DeleteUser_UserNotFound(t *testing.T) {
|
|
srvr := OpenServer(NewMessagingClient())
|
|
srvr.CreateDatabase("foo")
|
|
s := NewHTTPServer(srvr)
|
|
defer s.Close()
|
|
|
|
status, body := MustHTTP("DELETE", s.URL+`/users/jdoe`, "")
|
|
if status != http.StatusNotFound {
|
|
t.Fatalf("unexpected status: %d", status)
|
|
} else if body != `user not found` {
|
|
t.Fatalf("unexpected body: %s", body)
|
|
}
|
|
}
|
|
|
|
func TestHandler_DataNodes(t *testing.T) {
|
|
srvr := OpenUninitializedServer(NewMessagingClient())
|
|
srvr.CreateDataNode(MustParseURL("http://localhost:1000"))
|
|
srvr.CreateDataNode(MustParseURL("http://localhost:2000"))
|
|
srvr.CreateDataNode(MustParseURL("http://localhost:3000"))
|
|
s := NewHTTPServer(srvr)
|
|
defer s.Close()
|
|
|
|
status, body := MustHTTP("GET", s.URL+`/data_nodes`, "")
|
|
if status != http.StatusOK {
|
|
t.Fatalf("unexpected status: %d", status)
|
|
} else if body != `[{"id":1,"url":"http://localhost:1000"},{"id":2,"url":"http://localhost:2000"},{"id":3,"url":"http://localhost:3000"}]` {
|
|
t.Fatalf("unexpected body: %s", body)
|
|
}
|
|
}
|
|
|
|
func TestHandler_CreateDataNode(t *testing.T) {
|
|
srvr := OpenUninitializedServer(NewMessagingClient())
|
|
s := NewHTTPServer(srvr)
|
|
defer s.Close()
|
|
|
|
status, body := MustHTTP("POST", s.URL+`/data_nodes`, `{"url":"http://localhost:1000"}`)
|
|
if status != http.StatusCreated {
|
|
t.Fatalf("unexpected status: %d", status)
|
|
} else if body != `{"id":1,"url":"http://localhost:1000"}` {
|
|
t.Fatalf("unexpected body: %s", body)
|
|
}
|
|
}
|
|
|
|
func TestHandler_CreateDataNode_BadRequest(t *testing.T) {
|
|
srvr := OpenServer(NewMessagingClient())
|
|
s := NewHTTPServer(srvr)
|
|
defer s.Close()
|
|
|
|
status, body := MustHTTP("POST", s.URL+`/data_nodes`, `{"name":`)
|
|
if status != http.StatusBadRequest {
|
|
t.Fatalf("unexpected status: %d", status)
|
|
} else if body != `unexpected EOF` {
|
|
t.Fatalf("unexpected body: %s", body)
|
|
}
|
|
}
|
|
|
|
func TestHandler_CreateDataNode_InternalServerError(t *testing.T) {
|
|
srvr := OpenServer(NewMessagingClient())
|
|
s := NewHTTPServer(srvr)
|
|
defer s.Close()
|
|
|
|
status, body := MustHTTP("POST", s.URL+`/data_nodes`, `{"url":""}`)
|
|
if status != http.StatusInternalServerError {
|
|
t.Fatalf("unexpected status: %d, %s", status, body)
|
|
} else if body != `data node url required` {
|
|
t.Fatalf("unexpected body: %s", body)
|
|
}
|
|
}
|
|
|
|
func TestHandler_DeleteDataNode(t *testing.T) {
|
|
srvr := OpenServer(NewMessagingClient())
|
|
srvr.CreateDataNode(MustParseURL("http://localhost:1000"))
|
|
s := NewHTTPServer(srvr)
|
|
defer s.Close()
|
|
|
|
status, body := MustHTTP("DELETE", s.URL+`/data_nodes/1`, "")
|
|
if status != http.StatusNoContent {
|
|
t.Fatalf("unexpected status: %d", status)
|
|
} else if body != `` {
|
|
t.Fatalf("unexpected body: %s", body)
|
|
}
|
|
}
|
|
|
|
func TestHandler_DeleteUser_DataNodeNotFound(t *testing.T) {
|
|
srvr := OpenServer(NewMessagingClient())
|
|
s := NewHTTPServer(srvr)
|
|
defer s.Close()
|
|
|
|
status, body := MustHTTP("DELETE", s.URL+`/data_nodes/10000`, "")
|
|
if status != http.StatusNotFound {
|
|
t.Fatalf("unexpected status: %d", status)
|
|
} else if body != `data node not found` {
|
|
t.Fatalf("unexpected body: %s", body)
|
|
}
|
|
}
|
|
|
|
// Perform a subset of endpoint testing, with authentication enabled.
|
|
|
|
func TestHandler_AuthenticatedCreateAdminUser(t *testing.T) {
|
|
srvr := OpenServer(NewMessagingClient())
|
|
s := NewAuthenticatedHTTPServer(srvr)
|
|
defer s.Close()
|
|
|
|
// Attempting to create a non-admin user should fail.
|
|
status, _ := MustHTTP("POST", s.URL+`/users`, `{"name": "maeve", "password": "pass", "Admin": false}`)
|
|
if status != http.StatusUnauthorized {
|
|
t.Fatalf("unexpected status: %d", status)
|
|
}
|
|
|
|
// Creating the first admin user, without supplying authentication
|
|
// credentials should be OK.
|
|
status, _ = MustHTTP("POST", s.URL+`/users`, `{"name": "orla", "password": "pass", "Admin": true}`)
|
|
if status != http.StatusCreated {
|
|
t.Fatalf("unexpected status: %d", status)
|
|
}
|
|
|
|
// Creating a second admin user, without supplying authentication
|
|
// credentials should fail.
|
|
status, _ = MustHTTP("POST", s.URL+`/users`, `{"name": "louise", "password": "pass", "Admin": true}`)
|
|
if status != http.StatusUnauthorized {
|
|
t.Fatalf("unexpected status: %d", status)
|
|
}
|
|
|
|
}
|
|
|
|
func TestHandler_AuthenticatedDatabases_Unauthorized(t *testing.T) {
|
|
srvr := OpenServer(NewMessagingClient())
|
|
s := NewAuthenticatedHTTPServer(srvr)
|
|
defer s.Close()
|
|
|
|
status, _ := MustHTTP("GET", s.URL+`/db`, "")
|
|
if status != http.StatusUnauthorized {
|
|
t.Fatalf("unexpected status: %d", status)
|
|
}
|
|
}
|
|
|
|
func TestHandler_AuthenticatedDatabases_AuthorizedQueryParams(t *testing.T) {
|
|
srvr := OpenServer(NewMessagingClient())
|
|
srvr.CreateUser("lisa", "password", true)
|
|
s := NewAuthenticatedHTTPServer(srvr)
|
|
defer s.Close()
|
|
|
|
status, _ := MustHTTP("GET", s.URL+`/db?u=lisa&p=password`, "")
|
|
if status != http.StatusOK {
|
|
t.Fatalf("unexpected status: %d", status)
|
|
}
|
|
}
|
|
|
|
func TestHandler_AuthenticatedDatabases_AuthorizedBasicAuth(t *testing.T) {
|
|
srvr := OpenServer(NewMessagingClient())
|
|
srvr.CreateUser("lisa", "password", true)
|
|
s := NewAuthenticatedHTTPServer(srvr)
|
|
defer s.Close()
|
|
|
|
auth := make(map[string]string)
|
|
auth["Authorization"] = "Basic " + base64.StdEncoding.EncodeToString([]byte("lisa:password"))
|
|
fmt.Println(auth)
|
|
status, _ := MustHTTPWithHeaders("GET", s.URL+`/db`, auth, "")
|
|
if status != http.StatusOK {
|
|
t.Fatalf("unexpected status: %d", status)
|
|
}
|
|
}
|
|
|
|
// Utility functions for this test suite.
|
|
|
|
func MustHTTP(verb, url, body string) (int, string) {
|
|
return MustHTTPWithHeaders(verb, url, nil, body)
|
|
}
|
|
|
|
func MustHTTPWithHeaders(verb, url string, headers map[string]string, body string) (int, string) {
|
|
req, err := http.NewRequest(verb, url, bytes.NewBuffer([]byte(body)))
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
for k, v := range headers {
|
|
req.Header.Set(k, v)
|
|
}
|
|
req.Header.Set("Content-Type", "application/json")
|
|
|
|
client := &http.Client{}
|
|
resp, err := client.Do(req)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
b, err := ioutil.ReadAll(resp.Body)
|
|
return resp.StatusCode, strings.TrimRight(string(b), "\n")
|
|
}
|
|
|
|
// MustParseURL parses a string into a URL. Panic on error.
|
|
func MustParseURL(s string) *url.URL {
|
|
u, err := url.Parse(s)
|
|
if err != nil {
|
|
panic(err.Error())
|
|
}
|
|
return u
|
|
}
|
|
|
|
// Server is a test HTTP server that wraps a handler
|
|
type HTTPServer struct {
|
|
*httptest.Server
|
|
Handler *influxdb.Handler
|
|
}
|
|
|
|
func NewHTTPServer(s *Server) *HTTPServer {
|
|
h := influxdb.NewHandler(s.Server)
|
|
return &HTTPServer{httptest.NewServer(h), h}
|
|
}
|
|
|
|
func NewAuthenticatedHTTPServer(s *Server) *HTTPServer {
|
|
h := influxdb.NewHandler(s.Server)
|
|
h.AuthenticationEnabled = true
|
|
return &HTTPServer{httptest.NewServer(h), h}
|
|
}
|
|
|
|
func (s *HTTPServer) Close() {
|
|
s.Server.Close()
|
|
}
|