2014-11-19 17:12:46 +00:00
|
|
|
package influxdb_test
|
|
|
|
|
|
|
|
import (
|
2014-11-20 18:05:53 +00:00
|
|
|
"bytes"
|
2014-11-20 11:25:08 +00:00
|
|
|
"io/ioutil"
|
2014-11-19 17:12:46 +00:00
|
|
|
"net/http"
|
|
|
|
"net/http/httptest"
|
2014-11-20 11:25:08 +00:00
|
|
|
"strings"
|
2014-11-19 17:12:46 +00:00
|
|
|
"testing"
|
2014-11-20 11:25:08 +00:00
|
|
|
"time"
|
|
|
|
//"fmt"
|
2014-11-19 17:12:46 +00:00
|
|
|
"github.com/influxdb/influxdb"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestHandler_Shards(t *testing.T) {
|
2014-11-20 11:25:08 +00:00
|
|
|
srvr := OpenServer(NewMessagingClient())
|
|
|
|
srvr.CreateDatabase("foo")
|
|
|
|
db := srvr.Database("foo")
|
|
|
|
db.CreateRetentionPolicy(influxdb.NewRetentionPolicy("bar"))
|
|
|
|
db.CreateShardIfNotExists("bar", time.Time{})
|
2014-11-20 16:02:21 +00:00
|
|
|
s := NewHTTPServer(srvr)
|
2014-11-19 17:12:46 +00:00
|
|
|
defer s.Close()
|
2014-11-20 19:01:55 +00:00
|
|
|
status, body := MustHTTP("GET", s.URL + `/db/foo/shards`, "")
|
2014-11-20 11:25:08 +00:00
|
|
|
if status != http.StatusOK {
|
|
|
|
t.Fatalf("unexpected status: %d", status)
|
|
|
|
}
|
|
|
|
if body != `[{"id":3,"startTime":"0001-01-01T00:00:00Z","endTime":"0001-01-01T00:00:00Z"}]` {
|
|
|
|
t.Fatalf("unexpected body: %s", body)
|
2014-11-19 17:12:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-20 11:25:08 +00:00
|
|
|
func TestHandler_RetentionPolicies(t *testing.T) {
|
|
|
|
srvr := OpenServer(NewMessagingClient())
|
|
|
|
srvr.CreateDatabase("foo")
|
|
|
|
db := srvr.Database("foo")
|
|
|
|
db.CreateRetentionPolicy(influxdb.NewRetentionPolicy("bar"))
|
2014-11-20 16:02:21 +00:00
|
|
|
s := NewHTTPServer(srvr)
|
2014-11-19 18:30:39 +00:00
|
|
|
defer s.Close()
|
2014-11-20 19:01:55 +00:00
|
|
|
status, body := MustHTTP("GET", s.URL + `/db/foo/retention_policies`, "")
|
2014-11-20 11:25:08 +00:00
|
|
|
if status != http.StatusOK {
|
|
|
|
t.Fatalf("unexpected status: %d", status)
|
|
|
|
}
|
|
|
|
if body != `[{"name":"bar","replicaN":1,"splitN":1}]` {
|
|
|
|
t.Fatalf("unexpected body: %s", body)
|
2014-11-19 18:30:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-20 18:05:53 +00:00
|
|
|
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}`
|
2014-11-20 19:01:55 +00:00
|
|
|
status, body := MustHTTP("POST", s.URL + `/db/foo/retention_policies`, policy)
|
2014-11-20 18:05:53 +00:00
|
|
|
if status != http.StatusCreated {
|
|
|
|
t.Fatalf("unexpected status: %d", status)
|
|
|
|
}
|
|
|
|
if body != "" {
|
|
|
|
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": "bar", "duration": 1000000, "replicaN": 1, "splitN": 2}`
|
2014-11-20 19:01:55 +00:00
|
|
|
MustHTTP("POST", s.URL + `/db/foo/retention_policies`, policy)
|
|
|
|
status, body := MustHTTP("POST", s.URL + `/db/foo/retention_policies`, policy)
|
2014-11-20 18:05:53 +00:00
|
|
|
if status != http.StatusConflict {
|
|
|
|
t.Fatalf("unexpected status: %d", status)
|
|
|
|
}
|
|
|
|
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}`
|
2014-11-20 19:01:55 +00:00
|
|
|
status, body := MustHTTP("POST", s.URL + `/db/foo/retention_policies`, policy)
|
2014-11-20 18:05:53 +00:00
|
|
|
if status != http.StatusBadRequest {
|
|
|
|
t.Fatalf("unexpected status: %d", status)
|
|
|
|
}
|
|
|
|
if body != "json: cannot unmarshal string into Go value of type time.Duration" {
|
|
|
|
t.Fatalf("unexpected body: %s", body)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-20 19:01:55 +00:00
|
|
|
func TestHandler_DeleteRetentionPolicy(t *testing.T) {
|
|
|
|
srvr := OpenServer(NewMessagingClient())
|
|
|
|
srvr.CreateDatabase("foo")
|
|
|
|
db := srvr.Database("foo")
|
|
|
|
db.CreateRetentionPolicy(influxdb.NewRetentionPolicy("bar"))
|
|
|
|
s := NewHTTPServer(srvr)
|
|
|
|
defer s.Close()
|
|
|
|
status, body := MustHTTP("DELETE", s.URL + `/db/foo/retention_policies/bar`, "")
|
|
|
|
if status != http.StatusOK {
|
|
|
|
t.Fatalf("unexpected status: %d", status)
|
|
|
|
}
|
|
|
|
if body != "" {
|
|
|
|
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)
|
|
|
|
}
|
|
|
|
if body != "retention policy not found" {
|
|
|
|
t.Fatalf("unexpected body: %s", body)
|
|
|
|
}
|
2014-11-20 11:25:08 +00:00
|
|
|
}
|
|
|
|
|
2014-11-20 19:01:55 +00:00
|
|
|
func MustHTTP(verb, url, body string) (int, string) {
|
|
|
|
req, err := http.NewRequest(verb, url, bytes.NewBuffer([]byte(body)))
|
2014-11-20 18:05:53 +00:00
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
req.Header.Set("Content-Type", "applicaton/json")
|
|
|
|
client := &http.Client{}
|
|
|
|
resp, err := client.Do(req)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
defer resp.Body.Close()
|
|
|
|
status := resp.StatusCode
|
|
|
|
respBody, err := ioutil.ReadAll(resp.Body)
|
|
|
|
return status, strings.TrimRight(string(respBody), "\n")
|
|
|
|
}
|
|
|
|
|
2014-11-19 17:12:46 +00:00
|
|
|
// Server is a test HTTP server that wraps a handler
|
2014-11-20 16:02:21 +00:00
|
|
|
type HTTPServer struct {
|
2014-11-19 17:12:46 +00:00
|
|
|
*httptest.Server
|
|
|
|
Handler *influxdb.Handler
|
|
|
|
}
|
|
|
|
|
2014-11-20 16:02:21 +00:00
|
|
|
func NewHTTPServer(s *Server) *HTTPServer {
|
2014-11-19 17:12:46 +00:00
|
|
|
h := influxdb.NewHandler(s.Server)
|
2014-11-20 16:02:21 +00:00
|
|
|
return &HTTPServer{httptest.NewServer(h), h}
|
2014-11-19 17:12:46 +00:00
|
|
|
}
|
|
|
|
|
2014-11-20 16:02:21 +00:00
|
|
|
func (s *HTTPServer) Close() {
|
2014-11-19 17:12:46 +00:00
|
|
|
s.Server.Close()
|
|
|
|
}
|
2013-10-17 17:21:50 +00:00
|
|
|
|
2014-10-22 05:32:19 +00:00
|
|
|
/*
|
2013-10-17 17:21:50 +00:00
|
|
|
import (
|
2013-10-17 22:10:47 +00:00
|
|
|
"bytes"
|
2013-11-11 20:27:15 +00:00
|
|
|
"encoding/base64"
|
2013-10-17 17:21:50 +00:00
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
|
|
|
"io/ioutil"
|
|
|
|
"net"
|
2013-10-21 18:54:37 +00:00
|
|
|
libhttp "net/http"
|
2013-10-17 17:21:50 +00:00
|
|
|
"net/url"
|
|
|
|
"testing"
|
|
|
|
"time"
|
2014-05-29 17:49:04 +00:00
|
|
|
|
2014-06-27 16:57:06 +00:00
|
|
|
"github.com/influxdb/influxdb/cluster"
|
|
|
|
. "github.com/influxdb/influxdb/common"
|
|
|
|
"github.com/influxdb/influxdb/configuration"
|
|
|
|
"github.com/influxdb/influxdb/coordinator"
|
2014-08-20 15:59:45 +00:00
|
|
|
"github.com/influxdb/influxdb/engine"
|
2014-06-27 16:57:06 +00:00
|
|
|
"github.com/influxdb/influxdb/parser"
|
|
|
|
"github.com/influxdb/influxdb/protocol"
|
2014-05-13 20:35:51 +00:00
|
|
|
. "launchpad.net/gocheck"
|
2013-10-17 17:21:50 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// Hook up gocheck into the gotest runner.
|
|
|
|
func Test(t *testing.T) {
|
|
|
|
TestingT(t)
|
|
|
|
}
|
|
|
|
|
|
|
|
type ApiSuite struct {
|
2013-10-17 22:10:47 +00:00
|
|
|
listener net.Listener
|
|
|
|
server *HttpServer
|
|
|
|
coordinator *MockCoordinator
|
2013-10-22 23:44:03 +00:00
|
|
|
manager *MockUserManager
|
2013-10-17 17:21:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var _ = Suite(&ApiSuite{})
|
|
|
|
|
2014-08-20 15:59:45 +00:00
|
|
|
func (self *MockCoordinator) RunQuery(_ User, _ string, query string, yield engine.Processor) error {
|
2013-11-12 23:07:50 +00:00
|
|
|
if self.returnedError != nil {
|
|
|
|
return self.returnedError
|
|
|
|
}
|
|
|
|
|
2014-02-17 22:36:00 +00:00
|
|
|
series, err := StringToSeriesArray(`
|
2013-10-17 17:21:50 +00:00
|
|
|
[
|
|
|
|
{
|
|
|
|
"points": [
|
|
|
|
{
|
|
|
|
"values": [
|
2014-01-31 19:15:18 +00:00
|
|
|
{ "string_value": "some_value"},{"is_null": true}
|
2013-10-17 17:21:50 +00:00
|
|
|
],
|
2013-10-18 22:49:37 +00:00
|
|
|
"timestamp": 1381346631000000,
|
2013-10-17 17:21:50 +00:00
|
|
|
"sequence_number": 1
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"values": [
|
2013-10-18 17:18:51 +00:00
|
|
|
{"string_value": "some_value"},{"int64_value": 2}
|
2013-10-17 19:39:35 +00:00
|
|
|
],
|
2013-10-18 22:49:37 +00:00
|
|
|
"timestamp": 1381346632000000,
|
2013-10-17 17:21:50 +00:00
|
|
|
"sequence_number": 2
|
|
|
|
}
|
|
|
|
],
|
|
|
|
"name": "foo",
|
2013-10-23 22:00:13 +00:00
|
|
|
"fields": ["column_one", "column_two"]
|
2013-10-17 19:39:35 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
"points": [
|
2013-10-17 17:21:50 +00:00
|
|
|
{
|
2013-10-17 19:39:35 +00:00
|
|
|
"values": [
|
2013-10-18 17:18:51 +00:00
|
|
|
{ "string_value": "some_value"},{"int64_value": 3}
|
2013-10-17 19:39:35 +00:00
|
|
|
],
|
2013-10-18 22:49:37 +00:00
|
|
|
"timestamp": 1381346633000000,
|
2013-10-17 19:39:35 +00:00
|
|
|
"sequence_number": 1
|
2013-10-17 17:21:50 +00:00
|
|
|
},
|
|
|
|
{
|
2013-10-17 19:39:35 +00:00
|
|
|
"values": [
|
2013-10-18 17:18:51 +00:00
|
|
|
{"string_value": "some_value"},{"int64_value": 4}
|
2013-10-17 19:39:35 +00:00
|
|
|
],
|
2013-10-18 22:49:37 +00:00
|
|
|
"timestamp": 1381346634000000,
|
2013-10-17 19:39:35 +00:00
|
|
|
"sequence_number": 2
|
2013-10-17 17:21:50 +00:00
|
|
|
}
|
2013-10-17 19:39:35 +00:00
|
|
|
],
|
|
|
|
"name": "foo",
|
2013-10-23 22:00:13 +00:00
|
|
|
"fields": ["column_one", "column_two"]
|
2013-10-17 17:21:50 +00:00
|
|
|
}
|
|
|
|
]
|
|
|
|
`)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2014-08-20 15:59:45 +00:00
|
|
|
if _, err := yield.Yield(series[0]); err != nil {
|
2013-10-17 19:39:35 +00:00
|
|
|
return err
|
|
|
|
}
|
2014-08-20 15:59:45 +00:00
|
|
|
_, err = yield.Yield(series[1])
|
|
|
|
return err
|
2013-10-17 17:21:50 +00:00
|
|
|
}
|
|
|
|
|
2013-10-17 22:10:47 +00:00
|
|
|
type MockCoordinator struct {
|
2014-01-10 20:41:56 +00:00
|
|
|
coordinator.Coordinator
|
2013-12-23 22:30:21 +00:00
|
|
|
series []*protocol.Series
|
2014-01-31 20:40:10 +00:00
|
|
|
continuousQueries map[string][]*cluster.ContinuousQuery
|
2013-12-23 22:30:21 +00:00
|
|
|
deleteQueries []*parser.DeleteQuery
|
|
|
|
db string
|
|
|
|
droppedDb string
|
2014-02-03 23:19:36 +00:00
|
|
|
returnedError error
|
2013-10-17 22:10:47 +00:00
|
|
|
}
|
|
|
|
|
2014-04-07 20:30:52 +00:00
|
|
|
func (self *MockCoordinator) WriteSeriesData(_ User, db string, series []*protocol.Series) error {
|
|
|
|
self.series = append(self.series, series...)
|
2013-10-17 22:10:47 +00:00
|
|
|
return nil
|
|
|
|
}
|
2013-10-25 15:30:14 +00:00
|
|
|
|
2014-02-17 22:36:00 +00:00
|
|
|
func (self *MockCoordinator) DeleteSeriesData(_ User, db string, query *parser.DeleteQuery, localOnly bool) error {
|
2013-12-06 19:13:39 +00:00
|
|
|
self.deleteQueries = append(self.deleteQueries, query)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2014-05-15 18:39:53 +00:00
|
|
|
func (self *MockCoordinator) CreateDatabase(_ User, db string) error {
|
2013-10-20 18:29:26 +00:00
|
|
|
self.db = db
|
|
|
|
return nil
|
|
|
|
}
|
2013-10-17 22:10:47 +00:00
|
|
|
|
2014-02-17 22:36:00 +00:00
|
|
|
func (self *MockCoordinator) ListDatabases(_ User) ([]*cluster.Database, error) {
|
2014-06-23 17:14:00 +00:00
|
|
|
return []*cluster.Database{{"db1"}, {"db2"}}, nil
|
2013-10-25 17:01:44 +00:00
|
|
|
}
|
|
|
|
|
2014-02-17 22:36:00 +00:00
|
|
|
func (self *MockCoordinator) DropDatabase(_ User, db string) error {
|
2013-10-25 15:30:14 +00:00
|
|
|
self.droppedDb = db
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2014-02-17 22:36:00 +00:00
|
|
|
func (self *MockCoordinator) ListContinuousQueries(_ User, db string) ([]*protocol.Series, error) {
|
2013-12-23 22:30:21 +00:00
|
|
|
points := []*protocol.Point{}
|
|
|
|
|
|
|
|
for _, query := range self.continuousQueries[db] {
|
|
|
|
queryId := int64(query.Id)
|
|
|
|
queryString := query.Query
|
|
|
|
points = append(points, &protocol.Point{
|
|
|
|
Values: []*protocol.FieldValue{
|
2014-06-23 17:14:00 +00:00
|
|
|
{Int64Value: &queryId},
|
|
|
|
{StringValue: &queryString},
|
2013-12-23 22:30:21 +00:00
|
|
|
},
|
|
|
|
Timestamp: nil,
|
|
|
|
SequenceNumber: nil,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
seriesName := "continuous queries"
|
2014-06-23 17:14:00 +00:00
|
|
|
series := []*protocol.Series{{
|
2013-12-23 22:30:21 +00:00
|
|
|
Name: &seriesName,
|
|
|
|
Fields: []string{"id", "query"},
|
|
|
|
Points: points,
|
|
|
|
}}
|
|
|
|
return series, nil
|
|
|
|
}
|
|
|
|
|
2014-02-17 22:36:00 +00:00
|
|
|
func (self *MockCoordinator) CreateContinuousQuery(_ User, db string, query string) error {
|
2014-01-31 20:40:10 +00:00
|
|
|
self.continuousQueries[db] = append(self.continuousQueries[db], &cluster.ContinuousQuery{2, query})
|
2013-12-23 22:30:21 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2014-02-17 22:36:00 +00:00
|
|
|
func (self *MockCoordinator) DeleteContinuousQuery(_ User, db string, id uint32) error {
|
2013-12-23 22:30:21 +00:00
|
|
|
length := len(self.continuousQueries[db])
|
|
|
|
_, self.continuousQueries[db] = self.continuousQueries[db][length-1], self.continuousQueries[db][:length-1]
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2013-10-22 16:00:00 +00:00
|
|
|
func (self *ApiSuite) formatUrl(path string, args ...interface{}) string {
|
|
|
|
path = fmt.Sprintf(path, args...)
|
|
|
|
port := self.listener.Addr().(*net.TCPAddr).Port
|
|
|
|
return fmt.Sprintf("http://localhost:%d%s", port, path)
|
2013-10-21 20:58:52 +00:00
|
|
|
}
|
|
|
|
|
2013-10-17 17:21:50 +00:00
|
|
|
func (self *ApiSuite) SetUpSuite(c *C) {
|
2013-12-23 22:30:21 +00:00
|
|
|
self.coordinator = &MockCoordinator{
|
2014-01-31 20:40:10 +00:00
|
|
|
continuousQueries: map[string][]*cluster.ContinuousQuery{
|
2014-06-23 17:14:00 +00:00
|
|
|
"db1": {
|
|
|
|
{1, "select * from foo into bar;"},
|
2013-12-23 22:30:21 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
2014-02-11 03:03:28 +00:00
|
|
|
|
2013-10-25 17:01:44 +00:00
|
|
|
self.manager = &MockUserManager{
|
|
|
|
clusterAdmins: []string{"root"},
|
2014-06-23 17:14:00 +00:00
|
|
|
dbUsers: map[string]map[string]MockDbUser{"db1": {"db_user1": {Name: "db_user1", IsAdmin: false}}},
|
2013-10-25 17:01:44 +00:00
|
|
|
}
|
2014-08-15 17:51:24 +00:00
|
|
|
config := &configuration.Configuration{
|
|
|
|
ApiReadTimeout: 10 * time.Second,
|
|
|
|
}
|
2014-05-13 20:35:51 +00:00
|
|
|
self.server = NewHttpServer(
|
2014-08-15 17:51:24 +00:00
|
|
|
config,
|
2014-05-13 20:35:51 +00:00
|
|
|
self.coordinator,
|
|
|
|
self.manager,
|
2014-08-15 17:51:24 +00:00
|
|
|
cluster.NewClusterConfiguration(config, nil, nil, nil, nil),
|
2014-05-13 20:35:51 +00:00
|
|
|
nil)
|
2013-10-17 17:21:50 +00:00
|
|
|
var err error
|
2013-10-20 18:29:26 +00:00
|
|
|
self.listener, err = net.Listen("tcp4", ":8081")
|
2013-10-17 17:21:50 +00:00
|
|
|
c.Assert(err, IsNil)
|
|
|
|
go func() {
|
|
|
|
self.server.Serve(self.listener)
|
|
|
|
}()
|
|
|
|
time.Sleep(1 * time.Second)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (self *ApiSuite) TearDownSuite(c *C) {
|
|
|
|
self.server.Close()
|
|
|
|
}
|
|
|
|
|
2013-10-18 21:57:35 +00:00
|
|
|
func (self *ApiSuite) SetUpTest(c *C) {
|
|
|
|
self.coordinator.series = nil
|
2014-02-03 23:19:36 +00:00
|
|
|
self.coordinator.returnedError = nil
|
2013-10-23 14:55:53 +00:00
|
|
|
self.manager.ops = nil
|
2013-10-18 21:57:35 +00:00
|
|
|
}
|
|
|
|
|
2013-12-12 22:54:29 +00:00
|
|
|
func (self *ApiSuite) TestHealthCheck(c *C) {
|
|
|
|
url := self.formatUrl("/ping")
|
|
|
|
resp, err := libhttp.Get(url)
|
|
|
|
c.Assert(err, IsNil)
|
|
|
|
c.Assert(resp.StatusCode, Equals, libhttp.StatusOK)
|
|
|
|
resp.Body.Close()
|
|
|
|
}
|
|
|
|
|
2013-11-04 17:39:53 +00:00
|
|
|
func (self *ApiSuite) TestClusterAdminAuthentication(c *C) {
|
|
|
|
url := self.formatUrl("/cluster_admins/authenticate?u=root&p=root")
|
|
|
|
resp, err := libhttp.Get(url)
|
|
|
|
c.Assert(err, IsNil)
|
|
|
|
c.Assert(resp.StatusCode, Equals, libhttp.StatusOK)
|
|
|
|
resp.Body.Close()
|
|
|
|
|
|
|
|
url = self.formatUrl("/cluster_admins/authenticate?u=fail_auth&p=anypass")
|
|
|
|
resp, err = libhttp.Get(url)
|
|
|
|
c.Assert(err, IsNil)
|
|
|
|
c.Assert(resp.StatusCode, Equals, libhttp.StatusUnauthorized)
|
2013-11-11 20:27:15 +00:00
|
|
|
c.Assert(resp.Header.Get("WWW-Authenticate"), Equals, "Basic realm=\"influxdb\"")
|
|
|
|
resp.Body.Close()
|
2013-11-04 17:39:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (self *ApiSuite) TestDbUserAuthentication(c *C) {
|
2013-11-11 20:27:15 +00:00
|
|
|
url := self.formatUrl("/db/foo/authenticate?u=dbuser&p=password")
|
2013-11-04 17:39:53 +00:00
|
|
|
resp, err := libhttp.Get(url)
|
|
|
|
c.Assert(err, IsNil)
|
|
|
|
c.Assert(resp.StatusCode, Equals, libhttp.StatusOK)
|
|
|
|
resp.Body.Close()
|
|
|
|
|
|
|
|
url = self.formatUrl("/db/foo/authenticate?u=fail_auth&p=anypass")
|
|
|
|
resp, err = libhttp.Get(url)
|
|
|
|
c.Assert(err, IsNil)
|
|
|
|
c.Assert(resp.StatusCode, Equals, libhttp.StatusUnauthorized)
|
2013-11-11 20:27:15 +00:00
|
|
|
c.Assert(resp.Header.Get("WWW-Authenticate"), Equals, "Basic realm=\"influxdb\"")
|
|
|
|
resp.Body.Close()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (self *ApiSuite) TestDbUserBasicAuthentication(c *C) {
|
|
|
|
url := self.formatUrl("/db/foo/authenticate")
|
|
|
|
req, err := libhttp.NewRequest("GET", url, nil)
|
|
|
|
auth := base64.StdEncoding.EncodeToString([]byte("dbuser:password"))
|
|
|
|
req.Header.Add("Authorization", "Basic "+auth)
|
|
|
|
c.Assert(err, IsNil)
|
|
|
|
resp, err := libhttp.DefaultClient.Do(req)
|
|
|
|
c.Assert(err, IsNil)
|
|
|
|
c.Assert(resp.StatusCode, Equals, libhttp.StatusOK)
|
2013-11-04 17:39:53 +00:00
|
|
|
resp.Body.Close()
|
|
|
|
}
|
|
|
|
|
2013-12-29 18:30:49 +00:00
|
|
|
func (self *ApiSuite) TestQueryAsClusterAdmin(c *C) {
|
|
|
|
query := "select * from foo;"
|
|
|
|
query = url.QueryEscape(query)
|
|
|
|
addr := self.formatUrl("/db/foo/series?q=%s&u=root&p=root", query)
|
|
|
|
resp, err := libhttp.Get(addr)
|
|
|
|
c.Assert(err, IsNil)
|
|
|
|
defer resp.Body.Close()
|
|
|
|
c.Assert(resp.StatusCode, Equals, libhttp.StatusOK)
|
|
|
|
}
|
|
|
|
|
2013-10-26 16:21:17 +00:00
|
|
|
func (self *ApiSuite) TestQueryWithNullColumns(c *C) {
|
|
|
|
query := "select * from foo;"
|
|
|
|
query = url.QueryEscape(query)
|
|
|
|
addr := self.formatUrl("/db/foo/series?q=%s&time_precision=s&u=dbuser&p=password", query)
|
|
|
|
resp, err := libhttp.Get(addr)
|
|
|
|
c.Assert(err, IsNil)
|
|
|
|
defer resp.Body.Close()
|
|
|
|
c.Assert(resp.StatusCode, Equals, libhttp.StatusOK)
|
|
|
|
data, err := ioutil.ReadAll(resp.Body)
|
|
|
|
c.Assert(err, IsNil)
|
|
|
|
series := []SerializedSeries{}
|
|
|
|
err = json.Unmarshal(data, &series)
|
|
|
|
c.Assert(err, IsNil)
|
|
|
|
c.Assert(series, HasLen, 1)
|
|
|
|
c.Assert(series[0].Name, Equals, "foo")
|
|
|
|
// time, seq, column_one, column_two
|
|
|
|
c.Assert(series[0].Columns, HasLen, 4)
|
|
|
|
c.Assert(series[0].Points, HasLen, 4)
|
|
|
|
c.Assert(int(series[0].Points[0][0].(float64)), Equals, 1381346631)
|
|
|
|
c.Assert(series[0].Points[0][3], Equals, nil)
|
|
|
|
}
|
|
|
|
|
2013-11-12 23:07:50 +00:00
|
|
|
func (self *ApiSuite) TestQueryErrorPropagatesProperly(c *C) {
|
2014-02-03 23:19:36 +00:00
|
|
|
self.coordinator.returnedError = fmt.Errorf("some error")
|
2013-11-12 23:07:50 +00:00
|
|
|
query := "select * from does_not_exist;"
|
|
|
|
query = url.QueryEscape(query)
|
|
|
|
addr := self.formatUrl("/db/foo/series?q=%s&time_precision=s&u=dbuser&p=password", query)
|
|
|
|
resp, err := libhttp.Get(addr)
|
|
|
|
c.Assert(err, IsNil)
|
|
|
|
defer resp.Body.Close()
|
|
|
|
c.Assert(resp.StatusCode, Equals, libhttp.StatusBadRequest)
|
|
|
|
}
|
|
|
|
|
2014-10-07 17:48:23 +00:00
|
|
|
func (self *ApiSuite) TestUnauthorizedErrorWithCompression(c *C) {
|
|
|
|
addr := self.formatUrl("/cluster_admins/authenticate?u=fail_auth&p=invalidpassword")
|
|
|
|
req, err := libhttp.NewRequest("GET", addr, nil)
|
|
|
|
c.Assert(err, IsNil)
|
|
|
|
req.Header.Set("Accept-Encoding", "gzip")
|
|
|
|
resp, err := libhttp.DefaultClient.Do(req)
|
|
|
|
c.Assert(err, IsNil)
|
|
|
|
defer resp.Body.Close()
|
|
|
|
c.Assert(resp.StatusCode, Equals, libhttp.StatusUnauthorized)
|
|
|
|
c.Assert(resp.Header.Get("Content-Type"), Equals, "text/plain")
|
|
|
|
c.Assert(resp.Header.Get("Content-Encoding"), Equals, "gzip")
|
|
|
|
}
|
|
|
|
|
2013-10-18 22:49:37 +00:00
|
|
|
func (self *ApiSuite) TestQueryWithSecondsPrecision(c *C) {
|
|
|
|
query := "select * from foo where column_one == 'some_value';"
|
|
|
|
query = url.QueryEscape(query)
|
2013-10-25 20:03:52 +00:00
|
|
|
addr := self.formatUrl("/db/foo/series?q=%s&time_precision=s&u=dbuser&p=password", query)
|
2013-10-21 18:54:37 +00:00
|
|
|
resp, err := libhttp.Get(addr)
|
2013-10-18 22:49:37 +00:00
|
|
|
c.Assert(err, IsNil)
|
|
|
|
defer resp.Body.Close()
|
2013-10-21 18:54:37 +00:00
|
|
|
c.Assert(resp.StatusCode, Equals, libhttp.StatusOK)
|
2013-10-18 22:49:37 +00:00
|
|
|
data, err := ioutil.ReadAll(resp.Body)
|
|
|
|
c.Assert(err, IsNil)
|
|
|
|
series := []SerializedSeries{}
|
|
|
|
err = json.Unmarshal(data, &series)
|
|
|
|
c.Assert(err, IsNil)
|
|
|
|
c.Assert(series, HasLen, 1)
|
|
|
|
c.Assert(series[0].Name, Equals, "foo")
|
|
|
|
// time, seq, column_one, column_two
|
|
|
|
c.Assert(series[0].Columns, HasLen, 4)
|
|
|
|
c.Assert(series[0].Points, HasLen, 4)
|
|
|
|
c.Assert(int(series[0].Points[0][0].(float64)), Equals, 1381346631)
|
|
|
|
}
|
|
|
|
|
2013-11-15 15:45:27 +00:00
|
|
|
func (self *ApiSuite) TestQueryWithInvalidPrecision(c *C) {
|
|
|
|
query := "select * from foo where column_one == 'some_value';"
|
|
|
|
query = url.QueryEscape(query)
|
|
|
|
addr := self.formatUrl("/db/foo/series?q=%s&time_precision=foo&u=dbuser&p=password", query)
|
|
|
|
resp, err := libhttp.Get(addr)
|
|
|
|
c.Assert(err, IsNil)
|
|
|
|
defer resp.Body.Close()
|
|
|
|
c.Assert(resp.StatusCode, Equals, libhttp.StatusBadRequest)
|
|
|
|
c.Assert(resp.Header.Get("content-type"), Equals, "text/plain")
|
|
|
|
}
|
|
|
|
|
2013-10-17 19:39:35 +00:00
|
|
|
func (self *ApiSuite) TestNotChunkedQuery(c *C) {
|
2013-10-17 17:21:50 +00:00
|
|
|
query := "select * from foo where column_one == 'some_value';"
|
|
|
|
query = url.QueryEscape(query)
|
2013-10-25 20:03:52 +00:00
|
|
|
addr := self.formatUrl("/db/foo/series?q=%s&u=dbuser&p=password", query)
|
2013-10-21 18:54:37 +00:00
|
|
|
resp, err := libhttp.Get(addr)
|
2013-10-17 17:21:50 +00:00
|
|
|
c.Assert(err, IsNil)
|
|
|
|
defer resp.Body.Close()
|
2013-10-21 18:54:37 +00:00
|
|
|
c.Assert(resp.StatusCode, Equals, libhttp.StatusOK)
|
2013-11-12 19:39:56 +00:00
|
|
|
c.Assert(resp.Header.Get("content-type"), Equals, "application/json")
|
2013-10-17 17:21:50 +00:00
|
|
|
data, err := ioutil.ReadAll(resp.Body)
|
|
|
|
c.Assert(err, IsNil)
|
|
|
|
series := []SerializedSeries{}
|
|
|
|
err = json.Unmarshal(data, &series)
|
|
|
|
c.Assert(err, IsNil)
|
|
|
|
c.Assert(series, HasLen, 1)
|
|
|
|
c.Assert(series[0].Name, Equals, "foo")
|
|
|
|
// time, seq, column_one, column_two
|
|
|
|
c.Assert(series[0].Columns, HasLen, 4)
|
2013-10-17 19:39:35 +00:00
|
|
|
c.Assert(series[0].Points, HasLen, 4)
|
2013-10-18 22:49:37 +00:00
|
|
|
// timestamp precision is milliseconds by default
|
2013-12-02 03:53:56 +00:00
|
|
|
c.Assert(int64(series[0].Points[0][0].(float64)), Equals, int64(1381346631000))
|
2013-10-17 19:39:35 +00:00
|
|
|
}
|
|
|
|
|
2014-06-13 05:47:15 +00:00
|
|
|
func (self *ApiSuite) TestNotChunkedPrettyQuery(c *C) {
|
2014-06-20 21:07:49 +00:00
|
|
|
query := "select * from foo where column_one == 'some_value';"
|
|
|
|
query = url.QueryEscape(query)
|
|
|
|
addr := self.formatUrl("/db/foo/series?q=%s&u=dbuser&p=password&pretty=true", query)
|
|
|
|
resp, err := libhttp.Get(addr)
|
|
|
|
c.Assert(err, IsNil)
|
|
|
|
defer resp.Body.Close()
|
|
|
|
c.Assert(resp.StatusCode, Equals, libhttp.StatusOK)
|
|
|
|
c.Assert(resp.Header.Get("content-type"), Equals, "application/json")
|
|
|
|
data, err := ioutil.ReadAll(resp.Body)
|
|
|
|
c.Assert(err, IsNil)
|
|
|
|
series := []SerializedSeries{}
|
|
|
|
err = json.Unmarshal(data, &series)
|
|
|
|
c.Assert(err, IsNil)
|
|
|
|
c.Assert(series, HasLen, 1)
|
|
|
|
c.Assert(series[0].Name, Equals, "foo")
|
|
|
|
// time, seq, column_one, column_two
|
|
|
|
c.Assert(series[0].Columns, HasLen, 4)
|
|
|
|
c.Assert(series[0].Points, HasLen, 4)
|
|
|
|
// timestamp precision is milliseconds by default
|
|
|
|
c.Assert(int64(series[0].Points[0][0].(float64)), Equals, int64(1381346631000))
|
2014-06-13 05:47:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (self *ApiSuite) TestNotChunkedNotPrettyQuery(c *C) {
|
2014-06-20 21:07:49 +00:00
|
|
|
query := "select * from foo where column_one == 'some_value';"
|
|
|
|
query = url.QueryEscape(query)
|
|
|
|
addr := self.formatUrl("/db/foo/series?q=%s&u=dbuser&p=password&pretty=false", query)
|
|
|
|
resp, err := libhttp.Get(addr)
|
|
|
|
c.Assert(err, IsNil)
|
|
|
|
defer resp.Body.Close()
|
|
|
|
c.Assert(resp.StatusCode, Equals, libhttp.StatusOK)
|
|
|
|
c.Assert(resp.Header.Get("content-type"), Equals, "application/json")
|
|
|
|
data, err := ioutil.ReadAll(resp.Body)
|
|
|
|
c.Assert(err, IsNil)
|
|
|
|
series := []SerializedSeries{}
|
|
|
|
err = json.Unmarshal(data, &series)
|
|
|
|
c.Assert(err, IsNil)
|
|
|
|
c.Assert(series, HasLen, 1)
|
|
|
|
c.Assert(series[0].Name, Equals, "foo")
|
|
|
|
// time, seq, column_one, column_two
|
|
|
|
c.Assert(series[0].Columns, HasLen, 4)
|
|
|
|
c.Assert(series[0].Points, HasLen, 4)
|
|
|
|
// timestamp precision is milliseconds by default
|
|
|
|
c.Assert(int64(series[0].Points[0][0].(float64)), Equals, int64(1381346631000))
|
2014-06-13 05:47:15 +00:00
|
|
|
}
|
|
|
|
|
2013-10-17 19:39:35 +00:00
|
|
|
func (self *ApiSuite) TestChunkedQuery(c *C) {
|
|
|
|
query := "select * from foo where column_one == 'some_value';"
|
|
|
|
query = url.QueryEscape(query)
|
2013-10-25 20:03:52 +00:00
|
|
|
addr := self.formatUrl("/db/foo/series?q=%s&chunked=true&u=dbuser&p=password", query)
|
2013-10-21 18:54:37 +00:00
|
|
|
resp, err := libhttp.Get(addr)
|
2013-10-17 19:39:35 +00:00
|
|
|
c.Assert(err, IsNil)
|
|
|
|
defer resp.Body.Close()
|
2013-11-12 19:39:56 +00:00
|
|
|
c.Assert(resp.Header.Get("content-type"), Equals, "application/json")
|
2013-10-17 19:39:35 +00:00
|
|
|
|
|
|
|
for i := 0; i < 2; i++ {
|
|
|
|
chunk := make([]byte, 2048, 2048)
|
|
|
|
n, err := resp.Body.Read(chunk)
|
|
|
|
|
|
|
|
series := SerializedSeries{}
|
|
|
|
err = json.Unmarshal(chunk[0:n], &series)
|
|
|
|
c.Assert(err, IsNil)
|
|
|
|
c.Assert(series.Name, Equals, "foo")
|
|
|
|
// time, seq, column_one, column_two
|
|
|
|
c.Assert(series.Columns, HasLen, 4)
|
|
|
|
// each chunk should have 2 points
|
|
|
|
c.Assert(series.Points, HasLen, 2)
|
|
|
|
}
|
2013-10-17 17:21:50 +00:00
|
|
|
}
|
2013-10-17 22:10:47 +00:00
|
|
|
|
2014-06-13 05:47:15 +00:00
|
|
|
func (self *ApiSuite) TestPrettyChunkedQuery(c *C) {
|
2014-06-20 21:07:49 +00:00
|
|
|
query := "select * from foo where column_one == 'some_value';"
|
|
|
|
query = url.QueryEscape(query)
|
|
|
|
addr := self.formatUrl("/db/foo/series?q=%s&chunked=true&u=dbuser&p=password&pretty=true", query)
|
|
|
|
resp, err := libhttp.Get(addr)
|
|
|
|
c.Assert(err, IsNil)
|
|
|
|
defer resp.Body.Close()
|
|
|
|
c.Assert(resp.Header.Get("content-type"), Equals, "application/json")
|
|
|
|
|
|
|
|
for i := 0; i < 2; i++ {
|
|
|
|
chunk := make([]byte, 2048, 2048)
|
|
|
|
n, err := resp.Body.Read(chunk)
|
|
|
|
|
|
|
|
series := SerializedSeries{}
|
|
|
|
err = json.Unmarshal(chunk[0:n], &series)
|
|
|
|
c.Assert(err, IsNil)
|
|
|
|
c.Assert(series.Name, Equals, "foo")
|
|
|
|
// time, seq, column_one, column_two
|
|
|
|
c.Assert(series.Columns, HasLen, 4)
|
|
|
|
// each chunk should have 2 points
|
|
|
|
c.Assert(series.Points, HasLen, 2)
|
|
|
|
}
|
2014-06-13 05:47:15 +00:00
|
|
|
}
|
|
|
|
|
2013-10-18 22:49:37 +00:00
|
|
|
func (self *ApiSuite) TestWriteDataWithTimeInSeconds(c *C) {
|
|
|
|
data := `
|
|
|
|
[
|
|
|
|
{
|
|
|
|
"points": [
|
|
|
|
[1382131686, "1"]
|
|
|
|
],
|
|
|
|
"name": "foo",
|
|
|
|
"columns": ["time", "column_one"]
|
|
|
|
}
|
|
|
|
]
|
|
|
|
`
|
|
|
|
|
2013-10-25 20:03:52 +00:00
|
|
|
addr := self.formatUrl("/db/foo/series?time_precision=s&u=dbuser&p=password")
|
2013-10-21 18:54:37 +00:00
|
|
|
resp, err := libhttp.Post(addr, "application/json", bytes.NewBufferString(data))
|
2013-10-18 22:49:37 +00:00
|
|
|
c.Assert(err, IsNil)
|
2013-10-21 18:54:37 +00:00
|
|
|
c.Assert(resp.StatusCode, Equals, libhttp.StatusOK)
|
2013-10-18 22:49:37 +00:00
|
|
|
c.Assert(self.coordinator.series, HasLen, 1)
|
|
|
|
series := self.coordinator.series[0]
|
|
|
|
|
|
|
|
// check the types
|
|
|
|
c.Assert(series.Fields, HasLen, 1)
|
2013-10-23 22:00:13 +00:00
|
|
|
c.Assert(series.Fields[0], Equals, "column_one")
|
2013-10-18 22:49:37 +00:00
|
|
|
|
|
|
|
// check the values
|
|
|
|
c.Assert(series.Points, HasLen, 1)
|
|
|
|
c.Assert(*series.Points[0].Values[0].StringValue, Equals, "1")
|
|
|
|
c.Assert(*series.Points[0].GetTimestampInMicroseconds(), Equals, int64(1382131686000000))
|
|
|
|
}
|
|
|
|
|
2013-10-18 21:52:30 +00:00
|
|
|
func (self *ApiSuite) TestWriteDataWithTime(c *C) {
|
|
|
|
data := `
|
|
|
|
[
|
|
|
|
{
|
|
|
|
"points": [
|
|
|
|
[1382131686000, "1"]
|
|
|
|
],
|
|
|
|
"name": "foo",
|
|
|
|
"columns": ["time", "column_one"]
|
|
|
|
}
|
|
|
|
]
|
|
|
|
`
|
|
|
|
|
2013-10-25 20:03:52 +00:00
|
|
|
addr := self.formatUrl("/db/foo/series?u=dbuser&p=password")
|
2013-10-21 18:54:37 +00:00
|
|
|
resp, err := libhttp.Post(addr, "application/json", bytes.NewBufferString(data))
|
2013-10-18 21:52:30 +00:00
|
|
|
c.Assert(err, IsNil)
|
2013-10-21 18:54:37 +00:00
|
|
|
c.Assert(resp.StatusCode, Equals, libhttp.StatusOK)
|
2013-10-18 21:52:30 +00:00
|
|
|
c.Assert(self.coordinator.series, HasLen, 1)
|
|
|
|
series := self.coordinator.series[0]
|
|
|
|
|
|
|
|
// check the types
|
|
|
|
c.Assert(series.Fields, HasLen, 1)
|
2013-10-23 22:00:13 +00:00
|
|
|
c.Assert(series.Fields[0], Equals, "column_one")
|
2013-10-18 21:52:30 +00:00
|
|
|
|
|
|
|
// check the values
|
|
|
|
c.Assert(series.Points, HasLen, 1)
|
|
|
|
c.Assert(*series.Points[0].Values[0].StringValue, Equals, "1")
|
|
|
|
c.Assert(*series.Points[0].GetTimestampInMicroseconds(), Equals, int64(1382131686000000))
|
|
|
|
}
|
|
|
|
|
2013-11-14 23:44:31 +00:00
|
|
|
func (self *ApiSuite) TestWriteDataWithInvalidTime(c *C) {
|
|
|
|
data := `
|
|
|
|
[
|
|
|
|
{
|
|
|
|
"points": [
|
|
|
|
["foo", "1"]
|
|
|
|
],
|
|
|
|
"name": "foo",
|
|
|
|
"columns": ["time", "column_one"]
|
|
|
|
}
|
|
|
|
]
|
|
|
|
`
|
|
|
|
|
|
|
|
addr := self.formatUrl("/db/foo/series?u=dbuser&p=password")
|
|
|
|
resp, err := libhttp.Post(addr, "application/json", bytes.NewBufferString(data))
|
|
|
|
c.Assert(err, IsNil)
|
|
|
|
c.Assert(resp.StatusCode, Equals, libhttp.StatusBadRequest)
|
|
|
|
}
|
|
|
|
|
2013-11-14 21:55:21 +00:00
|
|
|
func (self *ApiSuite) TestWriteDataWithNull(c *C) {
|
|
|
|
data := `
|
|
|
|
[
|
|
|
|
{
|
|
|
|
"points": [
|
|
|
|
["1", 1, 1.0, true],
|
|
|
|
["2", 2, 2.0, false],
|
|
|
|
["3", 3, 3.0, null]
|
|
|
|
],
|
|
|
|
"name": "foo",
|
|
|
|
"columns": ["column_one", "column_two", "column_three", "column_four"]
|
|
|
|
}
|
|
|
|
]
|
|
|
|
`
|
|
|
|
|
|
|
|
addr := self.formatUrl("/db/foo/series?u=dbuser&p=password")
|
|
|
|
resp, err := libhttp.Post(addr, "application/json", bytes.NewBufferString(data))
|
|
|
|
c.Assert(err, IsNil)
|
|
|
|
c.Assert(resp.StatusCode, Equals, libhttp.StatusOK)
|
|
|
|
c.Assert(self.coordinator.series, HasLen, 1)
|
|
|
|
series := self.coordinator.series[0]
|
|
|
|
c.Assert(series.Fields, HasLen, 4)
|
|
|
|
|
|
|
|
// check the types
|
|
|
|
c.Assert(series.Fields[0], Equals, "column_one")
|
|
|
|
c.Assert(series.Fields[1], Equals, "column_two")
|
|
|
|
c.Assert(series.Fields[2], Equals, "column_three")
|
|
|
|
c.Assert(series.Fields[3], Equals, "column_four")
|
|
|
|
|
|
|
|
// check the values
|
|
|
|
c.Assert(series.Points, HasLen, 3)
|
|
|
|
c.Assert(*series.Points[2].Values[0].StringValue, Equals, "3")
|
|
|
|
c.Assert(*series.Points[2].Values[1].Int64Value, Equals, int64(3))
|
2014-06-23 20:05:12 +00:00
|
|
|
c.Assert(*series.Points[2].Values[2].DoubleValue, Equals, 3.0)
|
2014-01-31 19:15:18 +00:00
|
|
|
c.Assert(series.Points[2].Values[3].GetIsNull(), Equals, true)
|
2013-11-14 21:55:21 +00:00
|
|
|
}
|
|
|
|
|
2013-10-17 22:10:47 +00:00
|
|
|
func (self *ApiSuite) TestWriteData(c *C) {
|
|
|
|
data := `
|
|
|
|
[
|
|
|
|
{
|
|
|
|
"points": [
|
|
|
|
["1", 1, 1.0, true],
|
|
|
|
["2", 2, 2.0, false],
|
|
|
|
["3", 3, 3.0, true]
|
|
|
|
],
|
|
|
|
"name": "foo",
|
|
|
|
"columns": ["column_one", "column_two", "column_three", "column_four"]
|
|
|
|
}
|
|
|
|
]
|
|
|
|
`
|
|
|
|
|
2013-10-25 20:03:52 +00:00
|
|
|
addr := self.formatUrl("/db/foo/series?u=dbuser&p=password")
|
2013-10-21 18:54:37 +00:00
|
|
|
resp, err := libhttp.Post(addr, "application/json", bytes.NewBufferString(data))
|
2013-10-17 22:10:47 +00:00
|
|
|
c.Assert(err, IsNil)
|
2013-10-21 18:54:37 +00:00
|
|
|
c.Assert(resp.StatusCode, Equals, libhttp.StatusOK)
|
2013-10-17 22:10:47 +00:00
|
|
|
c.Assert(self.coordinator.series, HasLen, 1)
|
|
|
|
series := self.coordinator.series[0]
|
|
|
|
c.Assert(series.Fields, HasLen, 4)
|
|
|
|
|
|
|
|
// check the types
|
2013-10-23 22:00:13 +00:00
|
|
|
c.Assert(series.Fields[0], Equals, "column_one")
|
|
|
|
c.Assert(series.Fields[1], Equals, "column_two")
|
|
|
|
c.Assert(series.Fields[2], Equals, "column_three")
|
|
|
|
c.Assert(series.Fields[3], Equals, "column_four")
|
2013-10-17 22:10:47 +00:00
|
|
|
|
|
|
|
// check the values
|
|
|
|
c.Assert(series.Points, HasLen, 3)
|
|
|
|
c.Assert(*series.Points[0].Values[0].StringValue, Equals, "1")
|
2013-10-18 21:57:35 +00:00
|
|
|
c.Assert(*series.Points[0].Values[1].Int64Value, Equals, int64(1))
|
2014-06-23 20:05:12 +00:00
|
|
|
c.Assert(*series.Points[0].Values[2].DoubleValue, Equals, 1.0)
|
2013-10-17 22:10:47 +00:00
|
|
|
c.Assert(*series.Points[0].Values[3].BoolValue, Equals, true)
|
|
|
|
}
|
2013-10-20 18:29:26 +00:00
|
|
|
|
2013-12-29 18:30:49 +00:00
|
|
|
func (self *ApiSuite) TestWriteDataAsClusterAdmin(c *C) {
|
|
|
|
data := `
|
|
|
|
[
|
|
|
|
{
|
|
|
|
"points": [
|
|
|
|
["1", true]
|
|
|
|
],
|
|
|
|
"name": "foo",
|
|
|
|
"columns": ["column_one", "column_two"]
|
|
|
|
}
|
|
|
|
]
|
|
|
|
`
|
|
|
|
|
|
|
|
addr := self.formatUrl("/db/foo/series?u=root&p=root")
|
|
|
|
resp, err := libhttp.Post(addr, "application/json", bytes.NewBufferString(data))
|
|
|
|
c.Assert(err, IsNil)
|
|
|
|
c.Assert(resp.StatusCode, Equals, libhttp.StatusOK)
|
|
|
|
}
|
|
|
|
|
2013-10-20 18:29:26 +00:00
|
|
|
func (self *ApiSuite) TestCreateDatabase(c *C) {
|
|
|
|
data := `{"name": "foo", "apiKey": "bar"}`
|
2013-11-11 20:27:15 +00:00
|
|
|
addr := self.formatUrl("/db?api_key=asdf&u=root&p=root")
|
2013-10-21 18:54:37 +00:00
|
|
|
resp, err := libhttp.Post(addr, "application/json", bytes.NewBufferString(data))
|
2013-10-20 18:29:26 +00:00
|
|
|
c.Assert(err, IsNil)
|
|
|
|
_, err = ioutil.ReadAll(resp.Body)
|
|
|
|
c.Assert(err, IsNil)
|
2013-10-21 18:54:37 +00:00
|
|
|
c.Assert(resp.StatusCode, Equals, libhttp.StatusCreated)
|
2013-10-20 18:29:26 +00:00
|
|
|
c.Assert(self.coordinator.db, Equals, "foo")
|
|
|
|
}
|
2013-10-22 16:00:00 +00:00
|
|
|
|
2014-08-18 02:34:49 +00:00
|
|
|
func (self *ApiSuite) TestCreateDatabaseNameFailures(c *C) {
|
|
|
|
data := map[string]string{
|
|
|
|
`{"name": ""}`: "Unable to create database without name",
|
|
|
|
`{}`: "Unable to create database without name",
|
|
|
|
`{"not_name": "bar"}`: "Unable to create database without name",
|
|
|
|
`{"name": " "}`: "Unable to create database without name"}
|
|
|
|
for k, v := range data {
|
|
|
|
addr := self.formatUrl("/db?u=root&p=root")
|
|
|
|
resp, err := libhttp.Post(addr, "application/json", bytes.NewBufferString(k))
|
|
|
|
c.Assert(err, IsNil)
|
|
|
|
m, err := ioutil.ReadAll(resp.Body)
|
|
|
|
c.Assert(err, IsNil)
|
|
|
|
c.Assert(v, Equals, string(m))
|
|
|
|
c.Assert(resp.StatusCode, Equals, libhttp.StatusBadRequest)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-10-25 15:30:14 +00:00
|
|
|
func (self *ApiSuite) TestDropDatabase(c *C) {
|
|
|
|
addr := self.formatUrl("/db/foo?u=root&p=root")
|
|
|
|
req, err := libhttp.NewRequest("DELETE", addr, nil)
|
|
|
|
c.Assert(err, IsNil)
|
|
|
|
resp, err := libhttp.DefaultClient.Do(req)
|
|
|
|
c.Assert(err, IsNil)
|
|
|
|
_, err = ioutil.ReadAll(resp.Body)
|
|
|
|
c.Assert(err, IsNil)
|
|
|
|
c.Assert(resp.StatusCode, Equals, libhttp.StatusNoContent)
|
|
|
|
c.Assert(self.coordinator.droppedDb, Equals, "foo")
|
|
|
|
}
|
|
|
|
|
2013-10-22 23:44:03 +00:00
|
|
|
func (self *ApiSuite) TestClusterAdminOperations(c *C) {
|
2013-10-24 17:56:31 +00:00
|
|
|
url := self.formatUrl("/cluster_admins?u=root&p=root")
|
2013-12-03 18:35:57 +00:00
|
|
|
resp, err := libhttp.Post(url, "", bytes.NewBufferString(`{"name":"", "password": "new_pass"}`))
|
2013-11-07 20:46:50 +00:00
|
|
|
c.Assert(err, IsNil)
|
|
|
|
defer resp.Body.Close()
|
|
|
|
c.Assert(resp.StatusCode, Equals, libhttp.StatusBadRequest)
|
|
|
|
|
|
|
|
url = self.formatUrl("/cluster_admins?u=root&p=root")
|
2013-12-03 18:35:57 +00:00
|
|
|
resp, err = libhttp.Post(url, "", bytes.NewBufferString(`{"name":"new_user", "password": "new_pass"}`))
|
2013-10-22 23:44:03 +00:00
|
|
|
c.Assert(err, IsNil)
|
|
|
|
defer resp.Body.Close()
|
|
|
|
c.Assert(resp.StatusCode, Equals, libhttp.StatusOK)
|
2014-03-12 18:45:36 +00:00
|
|
|
c.Assert(self.manager.ops, HasLen, 1)
|
2013-10-23 14:55:53 +00:00
|
|
|
c.Assert(self.manager.ops[0].operation, Equals, "cluster_admin_add")
|
|
|
|
c.Assert(self.manager.ops[0].username, Equals, "new_user")
|
2014-03-12 18:45:36 +00:00
|
|
|
c.Assert(self.manager.ops[0].password, Equals, "new_pass")
|
2013-10-23 14:55:53 +00:00
|
|
|
self.manager.ops = nil
|
2013-10-22 23:44:03 +00:00
|
|
|
|
2013-10-24 17:56:31 +00:00
|
|
|
url = self.formatUrl("/cluster_admins/new_user?u=root&p=root")
|
2013-10-23 14:55:53 +00:00
|
|
|
resp, err = libhttp.Post(url, "", bytes.NewBufferString(`{"password":"new_password"}`))
|
2013-10-22 23:44:03 +00:00
|
|
|
c.Assert(err, IsNil)
|
|
|
|
defer resp.Body.Close()
|
|
|
|
c.Assert(resp.StatusCode, Equals, libhttp.StatusOK)
|
2013-10-23 14:55:53 +00:00
|
|
|
c.Assert(self.manager.ops, HasLen, 1)
|
|
|
|
c.Assert(self.manager.ops[0].operation, Equals, "cluster_admin_passwd")
|
|
|
|
c.Assert(self.manager.ops[0].username, Equals, "new_user")
|
|
|
|
c.Assert(self.manager.ops[0].password, Equals, "new_password")
|
|
|
|
self.manager.ops = nil
|
2013-10-22 23:44:03 +00:00
|
|
|
|
|
|
|
req, _ := libhttp.NewRequest("DELETE", url, nil)
|
|
|
|
resp, err = libhttp.DefaultClient.Do(req)
|
|
|
|
c.Assert(err, IsNil)
|
|
|
|
defer resp.Body.Close()
|
|
|
|
c.Assert(resp.StatusCode, Equals, libhttp.StatusOK)
|
2013-10-23 14:55:53 +00:00
|
|
|
c.Assert(self.manager.ops, HasLen, 1)
|
|
|
|
c.Assert(self.manager.ops[0].operation, Equals, "cluster_admin_del")
|
|
|
|
c.Assert(self.manager.ops[0].username, Equals, "new_user")
|
2013-10-22 23:44:03 +00:00
|
|
|
}
|
|
|
|
|
2013-11-12 20:39:35 +00:00
|
|
|
func (self *ApiSuite) TestDbUserOperations(c *C) {
|
2013-11-12 20:45:26 +00:00
|
|
|
// create user using the `name` field
|
2013-10-24 17:56:31 +00:00
|
|
|
url := self.formatUrl("/db/db1/users?u=root&p=root")
|
2013-11-12 20:45:26 +00:00
|
|
|
resp, err := libhttp.Post(url, "", bytes.NewBufferString(`{"name":"dbuser", "password": "password"}`))
|
|
|
|
c.Assert(err, IsNil)
|
|
|
|
defer resp.Body.Close()
|
|
|
|
c.Assert(resp.StatusCode, Equals, libhttp.StatusOK)
|
2014-03-12 18:45:36 +00:00
|
|
|
c.Assert(self.manager.ops, HasLen, 1)
|
2013-11-12 20:45:26 +00:00
|
|
|
c.Assert(self.manager.ops[0].operation, Equals, "db_user_add")
|
|
|
|
c.Assert(self.manager.ops[0].username, Equals, "dbuser")
|
2014-03-12 18:45:36 +00:00
|
|
|
c.Assert(self.manager.ops[0].password, Equals, "password")
|
2013-11-12 20:45:26 +00:00
|
|
|
self.manager.ops = nil
|
|
|
|
|
2013-11-11 20:27:15 +00:00
|
|
|
url = self.formatUrl("/db/db1/users/dbuser?u=root&p=root")
|
2013-10-23 14:55:53 +00:00
|
|
|
resp, err = libhttp.Post(url, "", bytes.NewBufferString(`{"password":"new_password"}`))
|
|
|
|
c.Assert(err, IsNil)
|
|
|
|
defer resp.Body.Close()
|
|
|
|
c.Assert(resp.StatusCode, Equals, libhttp.StatusOK)
|
|
|
|
c.Assert(self.manager.ops, HasLen, 1)
|
|
|
|
c.Assert(self.manager.ops[0].operation, Equals, "db_user_passwd")
|
2013-11-11 20:27:15 +00:00
|
|
|
c.Assert(self.manager.ops[0].username, Equals, "dbuser")
|
2013-10-23 14:55:53 +00:00
|
|
|
c.Assert(self.manager.ops[0].password, Equals, "new_password")
|
|
|
|
self.manager.ops = nil
|
|
|
|
|
2013-11-11 20:27:15 +00:00
|
|
|
// empty usernames aren't valid
|
2013-11-07 20:46:50 +00:00
|
|
|
url = self.formatUrl("/db/db1/users?u=root&p=root")
|
2013-12-03 18:35:57 +00:00
|
|
|
resp, err = libhttp.Post(url, "", bytes.NewBufferString(`{"name":"", "password": "password"}`))
|
2013-11-07 20:46:50 +00:00
|
|
|
c.Assert(err, IsNil)
|
|
|
|
defer resp.Body.Close()
|
|
|
|
c.Assert(resp.StatusCode, Equals, libhttp.StatusBadRequest)
|
|
|
|
|
2014-04-22 21:28:58 +00:00
|
|
|
// Fix #477 - Username should support @ character - https://github.com/influxdb/influxdb/issues/447
|
|
|
|
url = self.formatUrl("/db/db1/users?u=root&p=root")
|
|
|
|
resp, err = libhttp.Post(url, "", bytes.NewBufferString(`{"name":"paul@influxdb.com", "password": "password"}`))
|
|
|
|
c.Assert(err, IsNil)
|
|
|
|
defer resp.Body.Close()
|
|
|
|
c.Assert(resp.StatusCode, Equals, libhttp.StatusOK)
|
|
|
|
c.Assert(self.manager.ops, HasLen, 1)
|
|
|
|
c.Assert(self.manager.ops[0].operation, Equals, "db_user_add")
|
|
|
|
c.Assert(self.manager.ops[0].username, Equals, "paul@influxdb.com")
|
|
|
|
c.Assert(self.manager.ops[0].password, Equals, "password")
|
|
|
|
self.manager.ops = nil
|
|
|
|
|
2013-11-12 20:39:35 +00:00
|
|
|
// set and unset the db admin flag
|
|
|
|
url = self.formatUrl("/db/db1/users/dbuser?u=root&p=root")
|
|
|
|
resp, err = libhttp.Post(url, "", bytes.NewBufferString(`{"admin": true}`))
|
|
|
|
c.Assert(err, IsNil)
|
|
|
|
defer resp.Body.Close()
|
|
|
|
c.Assert(resp.StatusCode, Equals, libhttp.StatusOK)
|
|
|
|
c.Assert(self.manager.ops, HasLen, 1)
|
|
|
|
c.Assert(self.manager.ops[0].operation, Equals, "db_user_admin")
|
|
|
|
c.Assert(self.manager.ops[0].username, Equals, "dbuser")
|
|
|
|
c.Assert(self.manager.ops[0].isAdmin, Equals, true)
|
|
|
|
self.manager.ops = nil
|
|
|
|
url = self.formatUrl("/db/db1/users/dbuser?u=root&p=root")
|
|
|
|
resp, err = libhttp.Post(url, "", bytes.NewBufferString(`{"admin": false}`))
|
|
|
|
c.Assert(err, IsNil)
|
|
|
|
defer resp.Body.Close()
|
|
|
|
c.Assert(resp.StatusCode, Equals, libhttp.StatusOK)
|
|
|
|
c.Assert(self.manager.ops, HasLen, 1)
|
|
|
|
c.Assert(self.manager.ops[0].operation, Equals, "db_user_admin")
|
|
|
|
c.Assert(self.manager.ops[0].username, Equals, "dbuser")
|
|
|
|
c.Assert(self.manager.ops[0].isAdmin, Equals, false)
|
|
|
|
self.manager.ops = nil
|
|
|
|
|
2013-11-11 20:27:15 +00:00
|
|
|
url = self.formatUrl("/db/db1/users/dbuser?u=root&p=root")
|
2013-12-18 19:51:24 +00:00
|
|
|
req, _ := libhttp.NewRequest("DELETE", url, nil)
|
2013-10-23 14:55:53 +00:00
|
|
|
resp, err = libhttp.DefaultClient.Do(req)
|
|
|
|
c.Assert(err, IsNil)
|
|
|
|
defer resp.Body.Close()
|
|
|
|
c.Assert(resp.StatusCode, Equals, libhttp.StatusOK)
|
|
|
|
c.Assert(self.manager.ops, HasLen, 1)
|
|
|
|
c.Assert(self.manager.ops[0].operation, Equals, "db_user_del")
|
2013-11-11 20:27:15 +00:00
|
|
|
c.Assert(self.manager.ops[0].username, Equals, "dbuser")
|
2013-10-22 23:44:03 +00:00
|
|
|
}
|
2013-10-25 17:01:44 +00:00
|
|
|
|
|
|
|
func (self *ApiSuite) TestClusterAdminsIndex(c *C) {
|
|
|
|
url := self.formatUrl("/cluster_admins?u=root&p=root")
|
|
|
|
resp, err := libhttp.Get(url)
|
|
|
|
c.Assert(err, IsNil)
|
2013-11-12 19:39:56 +00:00
|
|
|
c.Assert(resp.Header.Get("content-type"), Equals, "application/json")
|
2013-10-25 17:01:44 +00:00
|
|
|
defer resp.Body.Close()
|
|
|
|
body, err := ioutil.ReadAll(resp.Body)
|
|
|
|
c.Assert(err, IsNil)
|
2014-02-25 21:11:34 +00:00
|
|
|
users := []*ApiUser{}
|
2013-10-25 17:01:44 +00:00
|
|
|
err = json.Unmarshal(body, &users)
|
|
|
|
c.Assert(err, IsNil)
|
2014-06-23 17:14:00 +00:00
|
|
|
c.Assert(users, DeepEquals, []*ApiUser{{"root"}})
|
2013-10-25 17:01:44 +00:00
|
|
|
}
|
|
|
|
|
2014-06-13 05:47:15 +00:00
|
|
|
func (self *ApiSuite) TestPrettyClusterAdminsIndex(c *C) {
|
2014-06-20 21:07:49 +00:00
|
|
|
url := self.formatUrl("/cluster_admins?u=root&p=root&pretty=true")
|
|
|
|
resp, err := libhttp.Get(url)
|
|
|
|
c.Assert(err, IsNil)
|
|
|
|
c.Assert(resp.Header.Get("content-type"), Equals, "application/json")
|
|
|
|
defer resp.Body.Close()
|
|
|
|
body, err := ioutil.ReadAll(resp.Body)
|
|
|
|
c.Assert(err, IsNil)
|
|
|
|
users := []*ApiUser{}
|
|
|
|
err = json.Unmarshal(body, &users)
|
|
|
|
c.Assert(err, IsNil)
|
2014-06-23 17:14:00 +00:00
|
|
|
c.Assert(users, DeepEquals, []*ApiUser{{"root"}})
|
2014-06-13 05:47:15 +00:00
|
|
|
}
|
|
|
|
|
2013-10-25 17:01:44 +00:00
|
|
|
func (self *ApiSuite) TestDbUsersIndex(c *C) {
|
|
|
|
url := self.formatUrl("/db/db1/users?u=root&p=root")
|
|
|
|
resp, err := libhttp.Get(url)
|
|
|
|
c.Assert(err, IsNil)
|
2013-11-12 19:39:56 +00:00
|
|
|
c.Assert(resp.Header.Get("content-type"), Equals, "application/json")
|
2013-10-25 17:01:44 +00:00
|
|
|
defer resp.Body.Close()
|
|
|
|
body, err := ioutil.ReadAll(resp.Body)
|
|
|
|
c.Assert(err, IsNil)
|
2014-02-11 03:03:28 +00:00
|
|
|
users := []*UserDetail{}
|
2013-10-25 17:01:44 +00:00
|
|
|
err = json.Unmarshal(body, &users)
|
|
|
|
c.Assert(err, IsNil)
|
2014-02-25 21:42:37 +00:00
|
|
|
c.Assert(users, HasLen, 1)
|
2014-06-16 18:39:49 +00:00
|
|
|
c.Assert(users[0], DeepEquals, &UserDetail{"db_user1", false, ".*", ".*"})
|
2013-10-25 17:01:44 +00:00
|
|
|
}
|
|
|
|
|
2014-06-13 05:47:15 +00:00
|
|
|
func (self *ApiSuite) TestPrettyDbUsersIndex(c *C) {
|
2014-06-20 21:07:49 +00:00
|
|
|
url := self.formatUrl("/db/db1/users?u=root&p=root&pretty=true")
|
|
|
|
resp, err := libhttp.Get(url)
|
|
|
|
c.Assert(err, IsNil)
|
|
|
|
c.Assert(resp.Header.Get("content-type"), Equals, "application/json")
|
|
|
|
defer resp.Body.Close()
|
|
|
|
body, err := ioutil.ReadAll(resp.Body)
|
|
|
|
c.Assert(err, IsNil)
|
|
|
|
users := []*UserDetail{}
|
|
|
|
err = json.Unmarshal(body, &users)
|
|
|
|
c.Assert(err, IsNil)
|
|
|
|
c.Assert(users, HasLen, 1)
|
2014-07-01 17:33:35 +00:00
|
|
|
c.Assert(users[0], DeepEquals, &UserDetail{"db_user1", false, ".*", ".*"})
|
2014-06-13 05:47:15 +00:00
|
|
|
}
|
|
|
|
|
2014-02-10 22:10:48 +00:00
|
|
|
func (self *ApiSuite) TestDbUserShow(c *C) {
|
|
|
|
url := self.formatUrl("/db/db1/users/db_user1?u=root&p=root")
|
|
|
|
resp, err := libhttp.Get(url)
|
|
|
|
c.Assert(err, IsNil)
|
|
|
|
c.Assert(resp.Header.Get("content-type"), Equals, "application/json")
|
|
|
|
defer resp.Body.Close()
|
|
|
|
body, err := ioutil.ReadAll(resp.Body)
|
|
|
|
c.Assert(err, IsNil)
|
|
|
|
userDetail := &UserDetail{}
|
|
|
|
err = json.Unmarshal(body, &userDetail)
|
|
|
|
c.Assert(err, IsNil)
|
2014-06-16 18:39:49 +00:00
|
|
|
c.Assert(userDetail, DeepEquals, &UserDetail{"db_user1", false, ".*", ".*"})
|
2013-10-25 17:01:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (self *ApiSuite) TestDatabasesIndex(c *C) {
|
2013-12-03 18:35:57 +00:00
|
|
|
for _, path := range []string{"/db?u=root&p=root", "/db?u=root&p=root"} {
|
2013-11-12 20:47:25 +00:00
|
|
|
url := self.formatUrl(path)
|
|
|
|
resp, err := libhttp.Get(url)
|
|
|
|
c.Assert(err, IsNil)
|
|
|
|
c.Assert(resp.Header.Get("content-type"), Equals, "application/json")
|
|
|
|
defer resp.Body.Close()
|
|
|
|
body, err := ioutil.ReadAll(resp.Body)
|
|
|
|
c.Assert(err, IsNil)
|
2014-02-25 21:42:37 +00:00
|
|
|
databases := []*cluster.Database{}
|
2014-02-10 22:10:05 +00:00
|
|
|
err = json.Unmarshal(body, &databases)
|
2013-11-12 20:47:25 +00:00
|
|
|
c.Assert(err, IsNil)
|
2014-02-25 21:42:37 +00:00
|
|
|
err = json.Unmarshal(body, &databases)
|
|
|
|
c.Assert(err, IsNil)
|
2014-06-23 17:14:00 +00:00
|
|
|
c.Assert(databases, DeepEquals, []*cluster.Database{{"db1"}, {"db2"}})
|
2013-11-12 20:47:25 +00:00
|
|
|
}
|
2013-10-25 17:01:44 +00:00
|
|
|
}
|
2013-11-11 20:27:15 +00:00
|
|
|
|
|
|
|
func (self *ApiSuite) TestBasicAuthentication(c *C) {
|
2013-12-03 18:35:57 +00:00
|
|
|
url := self.formatUrl("/db")
|
2013-11-11 20:27:15 +00:00
|
|
|
req, err := libhttp.NewRequest("GET", url, nil)
|
|
|
|
c.Assert(err, IsNil)
|
|
|
|
auth := base64.StdEncoding.EncodeToString([]byte("root:root"))
|
|
|
|
req.Header.Add("Authorization", "Basic "+auth)
|
|
|
|
resp, err := libhttp.DefaultClient.Do(req)
|
|
|
|
defer resp.Body.Close()
|
|
|
|
body, err := ioutil.ReadAll(resp.Body)
|
|
|
|
c.Assert(err, IsNil)
|
|
|
|
c.Assert(resp.StatusCode, Equals, libhttp.StatusOK)
|
2014-02-25 21:42:37 +00:00
|
|
|
databases := []*cluster.Database{}
|
|
|
|
c.Assert(err, IsNil)
|
2014-02-10 22:10:05 +00:00
|
|
|
err = json.Unmarshal(body, &databases)
|
2013-11-11 20:27:15 +00:00
|
|
|
c.Assert(err, IsNil)
|
2014-06-23 17:14:00 +00:00
|
|
|
c.Assert(databases, DeepEquals, []*cluster.Database{{"db1"}, {"db2"}})
|
2013-11-11 20:27:15 +00:00
|
|
|
}
|
2014-10-22 05:32:19 +00:00
|
|
|
*/
|