2015-01-20 17:50:13 +00:00
package httpd_test
2014-11-19 17:12:46 +00:00
import (
2014-11-20 18:05:53 +00:00
"bytes"
2015-01-05 23:47:12 +00:00
"encoding/base64"
2015-01-28 08:45:21 +00:00
"encoding/json"
2015-01-29 19:28:13 +00:00
"fmt"
2014-11-20 11:25:08 +00:00
"io/ioutil"
2014-11-19 17:12:46 +00:00
"net/http"
"net/http/httptest"
2014-12-29 23:12:51 +00:00
"net/url"
2015-01-20 17:50:13 +00:00
"os"
2015-01-28 16:50:14 +00:00
"reflect"
2014-11-20 11:25:08 +00:00
"strings"
2015-02-04 04:30:33 +00:00
"sync"
2014-11-19 17:12:46 +00:00
"testing"
2015-01-29 19:28:13 +00:00
"time"
2014-12-30 15:50:15 +00:00
2014-11-19 17:12:46 +00:00
"github.com/influxdb/influxdb"
2015-01-20 17:50:13 +00:00
"github.com/influxdb/influxdb/httpd"
2015-01-28 16:50:14 +00:00
"github.com/influxdb/influxdb/influxql"
2015-01-20 17:50:13 +00:00
"github.com/influxdb/influxdb/messaging"
2014-11-19 17:12:46 +00:00
)
2014-11-26 22:10:56 +00:00
func init ( ) {
influxdb . BcryptCost = 4
}
2015-01-29 19:28:13 +00:00
func TestBatchWrite_UnmarshalEpoch ( t * testing . T ) {
2015-01-30 20:36:41 +00:00
now := time . Now ( ) . UTC ( )
2015-01-29 19:28:13 +00:00
tests := [ ] struct {
name string
epoch int64
precision string
expected time . Time
} {
{
name : "nanoseconds" ,
epoch : now . UnixNano ( ) ,
precision : "n" ,
expected : now ,
} ,
{
name : "microseconds" ,
epoch : now . Round ( time . Microsecond ) . UnixNano ( ) / int64 ( time . Microsecond ) ,
precision : "u" ,
expected : now . Round ( time . Microsecond ) ,
} ,
{
name : "milliseconds" ,
epoch : now . Round ( time . Millisecond ) . UnixNano ( ) / int64 ( time . Millisecond ) ,
precision : "ms" ,
expected : now . Round ( time . Millisecond ) ,
} ,
{
name : "seconds" ,
epoch : now . Round ( time . Second ) . UnixNano ( ) / int64 ( time . Second ) ,
precision : "s" ,
expected : now . Round ( time . Second ) ,
} ,
{
name : "minutes" ,
epoch : now . Round ( time . Minute ) . UnixNano ( ) / int64 ( time . Minute ) ,
precision : "m" ,
expected : now . Round ( time . Minute ) ,
} ,
{
name : "hours" ,
epoch : now . Round ( time . Hour ) . UnixNano ( ) / int64 ( time . Hour ) ,
precision : "h" ,
expected : now . Round ( time . Hour ) ,
} ,
{
name : "max int64" ,
epoch : 9223372036854775807 ,
precision : "n" ,
expected : time . Unix ( 0 , 9223372036854775807 ) ,
} ,
{
name : "100 years from now" ,
epoch : now . Add ( time . Hour * 24 * 365 * 100 ) . UnixNano ( ) ,
precision : "n" ,
expected : now . Add ( time . Hour * 24 * 365 * 100 ) ,
} ,
}
for _ , test := range tests {
t . Logf ( "testing %q\n" , test . name )
data := [ ] byte ( fmt . Sprintf ( ` { "timestamp": %d, "precision":"%s"} ` , test . epoch , test . precision ) )
t . Logf ( "json: %s" , string ( data ) )
2015-02-03 23:06:39 +00:00
var bp influxdb . BatchPoints
err := json . Unmarshal ( data , & bp )
2015-01-29 19:28:13 +00:00
if err != nil {
2015-02-04 03:24:56 +00:00
t . Fatalf ( "unexpected error. expected: %v, actual: %v" , nil , err )
2015-01-29 19:28:13 +00:00
}
2015-02-03 23:06:39 +00:00
if ! bp . Timestamp . Equal ( test . expected ) {
t . Fatalf ( "Unexpected time. expected: %v, actual: %v" , test . expected , bp . Timestamp )
2015-01-29 19:28:13 +00:00
}
}
}
func TestBatchWrite_UnmarshalRFC ( t * testing . T ) {
now := time . Now ( )
tests := [ ] struct {
name string
rfc string
2015-01-29 19:32:31 +00:00
now time . Time
2015-01-29 19:28:13 +00:00
expected time . Time
} {
{
name : "RFC3339Nano" ,
rfc : time . RFC3339Nano ,
2015-01-29 19:32:31 +00:00
now : now ,
2015-01-29 19:28:13 +00:00
expected : now ,
} ,
{
name : "RFC3339" ,
rfc : time . RFC3339 ,
2015-01-29 19:32:31 +00:00
now : now . Round ( time . Second ) ,
2015-01-29 19:28:13 +00:00
expected : now . Round ( time . Second ) ,
} ,
}
for _ , test := range tests {
t . Logf ( "testing %q\n" , test . name )
2015-01-29 19:32:31 +00:00
ts := test . now . Format ( test . rfc )
2015-01-29 19:28:13 +00:00
data := [ ] byte ( fmt . Sprintf ( ` { "timestamp": %q} ` , ts ) )
t . Logf ( "json: %s" , string ( data ) )
2015-02-03 23:06:39 +00:00
var bp influxdb . BatchPoints
err := json . Unmarshal ( data , & bp )
2015-01-29 19:28:13 +00:00
if err != nil {
t . Fatalf ( "unexpected error. exptected: %v, actual: %v" , nil , err )
}
2015-02-03 23:06:39 +00:00
if ! bp . Timestamp . Equal ( test . expected ) {
t . Fatalf ( "Unexpected time. expected: %v, actual: %v" , test . expected , bp . Timestamp )
2015-01-29 19:28:13 +00:00
}
}
}
2014-11-21 14:27:59 +00:00
func TestHandler_Databases ( t * testing . T ) {
2015-02-05 22:54:32 +00:00
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
2014-11-21 14:27:59 +00:00
srvr . CreateDatabase ( "foo" )
srvr . CreateDatabase ( "bar" )
s := NewHTTPServer ( srvr )
defer s . Close ( )
2014-12-21 17:45:50 +00:00
2015-01-26 16:28:08 +00:00
status , body := MustHTTP ( "GET" , s . URL + ` /query ` , map [ string ] string { "q" : "SHOW DATABASES" } , nil , "" )
2014-11-21 14:27:59 +00:00
if status != http . StatusOK {
t . Fatalf ( "unexpected status: %d" , status )
2015-02-23 05:21:49 +00:00
} else if body != ` { "results":[ { "series":[ { "columns":["name"],"values":[["bar"],["foo"]]}]}]} ` {
2014-11-21 14:27:59 +00:00
t . Fatalf ( "unexpected body: %s" , body )
}
}
2015-01-23 23:07:16 +00:00
func TestHandler_DatabasesPrettyPrinted ( t * testing . T ) {
2015-02-05 22:54:32 +00:00
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
2015-01-23 23:07:16 +00:00
srvr . CreateDatabase ( "foo" )
srvr . CreateDatabase ( "bar" )
s := NewHTTPServer ( srvr )
defer s . Close ( )
2015-01-26 16:28:08 +00:00
status , body := MustHTTP ( "GET" , s . URL + ` /query ` , map [ string ] string { "q" : "SHOW DATABASES" , "pretty" : "true" } , nil , "" )
2015-01-23 23:07:16 +00:00
if status != http . StatusOK {
t . Fatalf ( "unexpected status: %d" , status )
2015-01-27 20:27:29 +00:00
} else if body != ` {
"results" : [
{
2015-02-23 05:21:49 +00:00
"series" : [
2015-01-27 20:27:29 +00:00
{
"columns" : [
2015-01-28 07:40:49 +00:00
"name"
2015-01-23 23:07:16 +00:00
] ,
2015-01-27 20:27:29 +00:00
"values" : [
[
"bar"
] ,
[
"foo"
]
2015-01-23 23:07:16 +00:00
]
2015-01-27 20:27:29 +00:00
}
]
}
]
} ` {
2015-01-23 23:07:16 +00:00
t . Fatalf ( "unexpected body: %s" , body )
}
}
2014-11-21 14:27:59 +00:00
func TestHandler_CreateDatabase ( t * testing . T ) {
2015-02-05 22:54:32 +00:00
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
2014-11-21 14:27:59 +00:00
s := NewHTTPServer ( srvr )
defer s . Close ( )
2014-12-21 17:45:50 +00:00
2015-01-13 19:16:26 +00:00
status , body := MustHTTP ( "GET" , s . URL + ` /query ` , map [ string ] string { "q" : "CREATE DATABASE foo" } , nil , "" )
2015-01-14 19:45:07 +00:00
if status != http . StatusOK {
2014-11-21 14:27:59 +00:00
t . Fatalf ( "unexpected status: %d" , status )
2015-01-27 20:27:29 +00:00
} else if body != ` { "results":[ { }]} ` {
2014-11-21 14:27:59 +00:00
t . Fatalf ( "unexpected body: %s" , body )
}
}
func TestHandler_CreateDatabase_BadRequest_NoName ( t * testing . T ) {
2015-02-05 22:54:32 +00:00
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
2014-11-21 14:27:59 +00:00
s := NewHTTPServer ( srvr )
defer s . Close ( )
2014-12-21 17:45:50 +00:00
2015-01-13 19:48:54 +00:00
status , _ := MustHTTP ( "GET" , s . URL + ` /query ` , map [ string ] string { "q" : "CREATE DATABASE" } , nil , "" )
2014-11-21 14:27:59 +00:00
if status != http . StatusBadRequest {
t . Fatalf ( "unexpected status: %d" , status )
}
}
func TestHandler_CreateDatabase_Conflict ( t * testing . T ) {
2015-02-05 22:54:32 +00:00
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
2014-11-21 14:27:59 +00:00
srvr . CreateDatabase ( "foo" )
s := NewHTTPServer ( srvr )
defer s . Close ( )
2014-12-21 17:45:50 +00:00
2015-01-13 19:48:54 +00:00
status , body := MustHTTP ( "GET" , s . URL + ` /query ` , map [ string ] string { "q" : "CREATE DATABASE foo" } , nil , "" )
2015-01-14 00:50:01 +00:00
if status != http . StatusInternalServerError {
2014-11-21 14:27:59 +00:00
t . Fatalf ( "unexpected status: %d" , status )
2015-01-27 20:27:29 +00:00
} else if body != ` { "results":[ { "error":"database exists"}]} ` {
2014-11-21 14:27:59 +00:00
t . Fatalf ( "unexpected body: %s" , body )
}
}
2015-02-23 18:46:08 +00:00
func TestHandler_DropDatabase ( t * testing . T ) {
2015-02-05 22:54:32 +00:00
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
2014-11-21 14:27:59 +00:00
srvr . CreateDatabase ( "foo" )
s := NewHTTPServer ( srvr )
defer s . Close ( )
2014-12-21 17:45:50 +00:00
2015-01-13 19:16:26 +00:00
status , body := MustHTTP ( "GET" , s . URL + ` /query ` , map [ string ] string { "q" : "DROP DATABASE foo" } , nil , "" )
2015-01-14 19:45:07 +00:00
if status != http . StatusOK {
2014-11-21 14:27:59 +00:00
t . Fatalf ( "unexpected status: %d" , status )
2015-01-27 20:27:29 +00:00
} else if body != ` { "results":[ { }]} ` {
2014-11-21 14:27:59 +00:00
t . Fatalf ( "unexpected body: %s" , body )
}
}
2015-02-23 18:46:08 +00:00
func TestHandler_DropDatabase_NotFound ( t * testing . T ) {
2015-02-05 22:54:32 +00:00
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
2014-11-21 14:27:59 +00:00
s := NewHTTPServer ( srvr )
defer s . Close ( )
2014-12-21 17:45:50 +00:00
2015-01-13 19:48:54 +00:00
status , body := MustHTTP ( "GET" , s . URL + ` /query ` , map [ string ] string { "q" : "DROP DATABASE bar" } , nil , "" )
2015-01-13 20:12:28 +00:00
if status != http . StatusInternalServerError {
2014-11-21 14:27:59 +00:00
t . Fatalf ( "unexpected status: %d" , status )
2015-01-27 20:27:29 +00:00
} else if body != ` { "results":[ { "error":"database not found"}]} ` {
2014-11-21 14:27:59 +00:00
t . Fatalf ( "unexpected body: %s" , body )
}
}
2014-11-20 11:25:08 +00:00
func TestHandler_RetentionPolicies ( t * testing . T ) {
2015-02-05 22:54:32 +00:00
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
2014-11-20 11:25:08 +00:00
srvr . CreateDatabase ( "foo" )
2014-12-23 06:18:05 +00:00
srvr . CreateRetentionPolicy ( "foo" , 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-12-21 17:45:50 +00:00
2015-01-26 16:28:08 +00:00
status , body := MustHTTP ( "GET" , s . URL + ` /query ` , map [ string ] string { "q" : "SHOW RETENTION POLICIES foo" } , nil , "" )
2014-12-21 17:45:50 +00:00
2014-11-20 11:25:08 +00:00
if status != http . StatusOK {
t . Fatalf ( "unexpected status: %d" , status )
2015-02-23 05:21:49 +00:00
} else if body != ` { "results":[ { "series":[ { "columns":["name","duration","replicaN"],"values":[["bar","168h0m0s",1]]}]}]} ` {
2014-11-20 11:25:08 +00:00
t . Fatalf ( "unexpected body: %s" , body )
2014-11-19 18:30:39 +00:00
}
}
2014-11-21 14:27:59 +00:00
func TestHandler_RetentionPolicies_DatabaseNotFound ( t * testing . T ) {
2015-02-05 22:54:32 +00:00
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
2014-11-21 14:27:59 +00:00
s := NewHTTPServer ( srvr )
defer s . Close ( )
2014-12-21 17:45:50 +00:00
2015-01-26 16:28:08 +00:00
status , body := MustHTTP ( "GET" , s . URL + ` /query ` , map [ string ] string { "q" : "SHOW RETENTION POLICIES foo" } , nil , "" )
2014-12-21 17:45:50 +00:00
2015-01-14 04:50:29 +00:00
if status != http . StatusInternalServerError {
2014-11-21 14:27:59 +00:00
t . Fatalf ( "unexpected status: %d" , status )
2015-01-27 20:27:29 +00:00
} else if body != ` { "results":[ { "error":"database not found"}]} ` {
2014-11-21 14:27:59 +00:00
t . Fatalf ( "unexpected body: %s" , body )
}
}
2014-11-20 18:05:53 +00:00
func TestHandler_CreateRetentionPolicy ( t * testing . T ) {
2015-02-05 22:54:32 +00:00
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
2014-11-20 18:05:53 +00:00
srvr . CreateDatabase ( "foo" )
s := NewHTTPServer ( srvr )
defer s . Close ( )
2014-12-21 17:45:50 +00:00
2015-01-13 20:12:28 +00:00
query := map [ string ] string { "q" : "CREATE RETENTION POLICY bar ON foo DURATION 1h REPLICATION 1" }
status , body := MustHTTP ( "GET" , s . URL + ` /query ` , query , nil , "" )
2014-12-21 17:45:50 +00:00
2015-01-14 19:45:07 +00:00
if status != http . StatusOK {
2014-11-20 18:05:53 +00:00
t . Fatalf ( "unexpected status: %d" , status )
2015-01-27 20:27:29 +00:00
} else if body != ` { "results":[ { }]} ` {
2014-11-20 18:05:53 +00:00
t . Fatalf ( "unexpected body: %s" , body )
}
}
2015-01-28 19:27:05 +00:00
func TestHandler_CreateRetentionPolicyAsDefault ( t * testing . T ) {
2015-02-05 22:54:32 +00:00
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
2015-01-28 19:27:05 +00:00
srvr . CreateDatabase ( "foo" )
s := NewHTTPServer ( srvr )
defer s . Close ( )
query := map [ string ] string { "q" : "CREATE RETENTION POLICY bar ON foo DURATION 1h REPLICATION 1 DEFAULT" }
status , body := MustHTTP ( "GET" , s . URL + ` /query ` , query , nil , "" )
if status != http . StatusOK {
t . Fatalf ( "unexpected status: %d" , status )
} else if body != ` { "results":[ { }]} ` {
t . Fatalf ( "unexpected body: %s" , body )
}
rp , err := srvr . DefaultRetentionPolicy ( "foo" )
if err != nil {
t . Fatal ( err )
} else if rp . Name != "bar" {
t . Fatalf ( "default retention policy mismatch:\n exp=%s\n got=%s\n" , "bar" , rp . Name )
}
}
2014-11-21 14:27:59 +00:00
func TestHandler_CreateRetentionPolicy_DatabaseNotFound ( t * testing . T ) {
2015-02-05 22:54:32 +00:00
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
2014-11-21 14:27:59 +00:00
s := NewHTTPServer ( srvr )
defer s . Close ( )
2014-12-21 17:45:50 +00:00
2015-01-13 20:12:28 +00:00
query := map [ string ] string { "q" : "CREATE RETENTION POLICY bar ON foo DURATION 1h REPLICATION 1" }
status , _ := MustHTTP ( "GET" , s . URL + ` /query ` , query , nil , "" )
2014-12-21 17:45:50 +00:00
2015-01-13 20:12:28 +00:00
if status != http . StatusInternalServerError {
2014-11-21 14:27:59 +00:00
t . Fatalf ( "unexpected status: %d" , status )
}
}
2014-11-20 18:05:53 +00:00
func TestHandler_CreateRetentionPolicy_Conflict ( t * testing . T ) {
2015-02-05 22:54:32 +00:00
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
2014-11-20 18:05:53 +00:00
srvr . CreateDatabase ( "foo" )
s := NewHTTPServer ( srvr )
defer s . Close ( )
2014-12-21 17:45:50 +00:00
2015-01-13 20:12:28 +00:00
query := map [ string ] string { "q" : "CREATE RETENTION POLICY bar ON foo DURATION 1h REPLICATION 1" }
MustHTTP ( "GET" , s . URL + ` /query ` , query , nil , "" )
2014-12-21 17:45:50 +00:00
2015-01-13 20:12:28 +00:00
status , _ := MustHTTP ( "GET" , s . URL + ` /query ` , query , nil , "" )
if status != http . StatusInternalServerError {
2014-11-20 18:05:53 +00:00
t . Fatalf ( "unexpected status: %d" , status )
}
}
func TestHandler_CreateRetentionPolicy_BadRequest ( t * testing . T ) {
2015-02-05 22:54:32 +00:00
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
2014-11-20 18:05:53 +00:00
srvr . CreateDatabase ( "foo" )
s := NewHTTPServer ( srvr )
defer s . Close ( )
2014-12-21 17:45:50 +00:00
2015-01-13 20:12:28 +00:00
query := map [ string ] string { "q" : "CREATE RETENTION POLICY bar ON foo DURATION ***BAD*** REPLICATION 1" }
status , _ := MustHTTP ( "GET" , s . URL + ` /query ` , query , nil , "" )
2014-12-21 17:45:50 +00:00
2014-11-20 18:05:53 +00:00
if status != http . StatusBadRequest {
t . Fatalf ( "unexpected status: %d" , status )
}
}
2014-11-20 22:48:25 +00:00
func TestHandler_UpdateRetentionPolicy ( t * testing . T ) {
2015-02-05 22:54:32 +00:00
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
2014-11-20 22:48:25 +00:00
srvr . CreateDatabase ( "foo" )
2014-12-23 06:18:05 +00:00
srvr . CreateRetentionPolicy ( "foo" , influxdb . NewRetentionPolicy ( "bar" ) )
2014-11-20 22:48:25 +00:00
s := NewHTTPServer ( srvr )
defer s . Close ( )
2015-02-05 17:54:06 +00:00
query := map [ string ] string { "q" : "ALTER RETENTION POLICY bar ON foo REPLICATION 42 DURATION 1m DEFAULT" }
2015-01-14 05:22:36 +00:00
status , body := MustHTTP ( "GET" , s . URL + ` /query ` , query , nil , "" )
2014-12-21 17:45:50 +00:00
2014-12-23 06:18:05 +00:00
// Verify updated policy.
2015-01-14 05:22:36 +00:00
p , _ := srvr . RetentionPolicy ( "foo" , "bar" )
2015-01-14 19:45:07 +00:00
if status != http . StatusOK {
2014-11-20 22:48:25 +00:00
t . Fatalf ( "unexpected status: %d" , status )
2015-02-05 17:54:06 +00:00
} else if body != ` { "results":[ { }]} ` {
2014-11-20 22:48:25 +00:00
t . Fatalf ( "unexpected body: %s" , body )
2015-01-14 05:22:36 +00:00
} else if p . ReplicaN != 42 {
t . Fatalf ( "unexpected replication factor: %d" , p . ReplicaN )
2014-11-20 22:48:25 +00:00
}
2015-02-05 17:54:06 +00:00
// Make sure retention policy has been set as default.
if p , err := srvr . DefaultRetentionPolicy ( "foo" ) ; err != nil {
t . Fatal ( err )
} else if p == nil {
t . Fatal ( "default retention policy not set" )
} else if p . Name != "bar" {
t . Fatal ( ` expected default retention policy to be "bar" ` )
}
2014-11-20 22:48:25 +00:00
}
2014-11-21 14:27:59 +00:00
func TestHandler_UpdateRetentionPolicy_BadRequest ( t * testing . T ) {
2015-02-05 22:54:32 +00:00
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
2014-11-21 14:27:59 +00:00
srvr . CreateDatabase ( "foo" )
2014-12-23 06:18:05 +00:00
srvr . CreateRetentionPolicy ( "foo" , influxdb . NewRetentionPolicy ( "bar" ) )
2014-11-21 14:27:59 +00:00
s := NewHTTPServer ( srvr )
defer s . Close ( )
2015-01-13 20:12:28 +00:00
query := map [ string ] string { "q" : "ALTER RETENTION POLICY bar ON foo DURATION ***BAD*** REPLICATION 1" }
status , _ := MustHTTP ( "GET" , s . URL + ` /query ` , query , nil , "" )
2014-12-21 17:45:50 +00:00
2014-12-23 06:18:05 +00:00
// Verify response.
2014-11-21 14:27:59 +00:00
if status != http . StatusBadRequest {
t . Fatalf ( "unexpected status: %d" , status )
}
}
func TestHandler_UpdateRetentionPolicy_DatabaseNotFound ( t * testing . T ) {
2015-02-05 22:54:32 +00:00
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
2014-11-21 14:27:59 +00:00
s := NewHTTPServer ( srvr )
defer s . Close ( )
2015-01-13 20:12:28 +00:00
query := map [ string ] string { "q" : "ALTER RETENTION POLICY bar ON foo DURATION 1h REPLICATION 1" }
status , _ := MustHTTP ( "GET" , s . URL + ` /query ` , query , nil , "" )
2014-12-21 17:45:50 +00:00
2015-01-13 20:12:28 +00:00
// Verify response.
if status != http . StatusInternalServerError {
2014-11-21 14:27:59 +00:00
t . Fatalf ( "unexpected status: %d" , status )
}
}
2014-11-20 22:48:25 +00:00
func TestHandler_UpdateRetentionPolicy_NotFound ( t * testing . T ) {
2015-02-05 22:54:32 +00:00
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
2014-11-20 22:48:25 +00:00
srvr . CreateDatabase ( "foo" )
2015-01-13 20:12:28 +00:00
srvr . CreateRetentionPolicy ( "foo" , influxdb . NewRetentionPolicy ( "bar" ) )
2014-11-20 22:48:25 +00:00
s := NewHTTPServer ( srvr )
defer s . Close ( )
2015-01-13 20:12:28 +00:00
query := map [ string ] string { "q" : "ALTER RETENTION POLICY qux ON foo DURATION 1h REPLICATION 1" }
status , _ := MustHTTP ( "GET" , s . URL + ` /query ` , query , nil , "" )
2014-12-21 17:45:50 +00:00
2015-01-13 20:12:28 +00:00
// Verify response.
if status != http . StatusInternalServerError {
2014-11-20 22:48:25 +00:00
t . Fatalf ( "unexpected status: %d" , status )
}
}
2014-11-20 19:01:55 +00:00
func TestHandler_DeleteRetentionPolicy ( t * testing . T ) {
2015-02-05 22:54:32 +00:00
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
2014-11-20 19:01:55 +00:00
srvr . CreateDatabase ( "foo" )
2014-12-23 06:18:05 +00:00
srvr . CreateRetentionPolicy ( "foo" , influxdb . NewRetentionPolicy ( "bar" ) )
2014-11-20 19:01:55 +00:00
s := NewHTTPServer ( srvr )
defer s . Close ( )
2014-12-21 17:45:50 +00:00
2015-01-14 05:22:36 +00:00
query := map [ string ] string { "q" : "DROP RETENTION POLICY bar ON foo" }
status , body := MustHTTP ( "GET" , s . URL + ` /query ` , query , nil , "" )
2015-01-14 19:45:07 +00:00
if status != http . StatusOK {
2014-11-20 19:01:55 +00:00
t . Fatalf ( "unexpected status: %d" , status )
2015-01-27 20:27:29 +00:00
} else if body != ` { "results":[ { }]} ` {
2014-11-20 19:01:55 +00:00
t . Fatalf ( "unexpected body: %s" , body )
}
}
2014-11-21 14:27:59 +00:00
func TestHandler_DeleteRetentionPolicy_DatabaseNotFound ( t * testing . T ) {
2015-02-05 22:54:32 +00:00
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
2014-11-21 14:27:59 +00:00
s := NewHTTPServer ( srvr )
defer s . Close ( )
2014-12-21 17:45:50 +00:00
2015-01-14 05:22:36 +00:00
query := map [ string ] string { "q" : "DROP RETENTION POLICY bar ON qux" }
status , body := MustHTTP ( "GET" , s . URL + ` /query ` , query , nil , "" )
2014-12-21 17:45:50 +00:00
2015-01-14 05:22:36 +00:00
if status != http . StatusInternalServerError {
2014-11-21 14:27:59 +00:00
t . Fatalf ( "unexpected status: %d" , status )
2015-01-27 20:27:29 +00:00
} else if body != ` { "results":[ { "error":"database not found"}]} ` {
2014-11-21 14:27:59 +00:00
t . Fatalf ( "unexpected body: %s" , body )
}
}
2014-11-20 19:01:55 +00:00
func TestHandler_DeleteRetentionPolicy_NotFound ( t * testing . T ) {
2015-02-05 22:54:32 +00:00
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
2014-11-20 19:01:55 +00:00
srvr . CreateDatabase ( "foo" )
s := NewHTTPServer ( srvr )
defer s . Close ( )
2014-12-21 17:45:50 +00:00
2015-01-14 05:22:36 +00:00
query := map [ string ] string { "q" : "DROP RETENTION POLICY bar ON foo" }
status , body := MustHTTP ( "GET" , s . URL + ` /query ` , query , nil , "" )
2014-12-21 17:45:50 +00:00
2015-01-14 05:22:36 +00:00
if status != http . StatusInternalServerError {
2014-11-20 19:01:55 +00:00
t . Fatalf ( "unexpected status: %d" , status )
2015-01-27 20:27:29 +00:00
} else if body != ` { "results":[ { "error":"retention policy not found"}]} ` {
2014-11-20 19:01:55 +00:00
t . Fatalf ( "unexpected body: %s" , body )
}
2014-11-20 11:25:08 +00:00
}
2015-02-05 00:51:10 +00:00
func TestHandler_GzipEnabled ( t * testing . T ) {
2015-02-05 22:54:32 +00:00
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
2015-02-05 00:51:10 +00:00
s := NewHTTPServer ( srvr )
defer s . Close ( )
req , err := http . NewRequest ( "GET" , s . URL + ` /ping ` , bytes . NewBuffer ( [ ] byte { } ) )
if err != nil {
panic ( err )
}
req . Header . Set ( "Content-Type" , "application/json" )
req . Header . Set ( "Accept-Encoding" , "gzip" )
client := & http . Client { }
resp , err := client . Do ( req )
if err != nil {
panic ( err )
}
if ce := resp . Header . Get ( "Content-Encoding" ) ; ce != "gzip" {
t . Fatalf ( "unexpected Content-Encoding. expected %q, actual: %q" , "gzip" , ce )
}
}
func TestHandler_GzipDisabled ( t * testing . T ) {
2015-02-05 22:54:32 +00:00
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
2015-02-05 00:51:10 +00:00
s := NewHTTPServer ( srvr )
defer s . Close ( )
req , err := http . NewRequest ( "GET" , s . URL + ` /ping ` , bytes . NewBuffer ( [ ] byte { } ) )
if err != nil {
panic ( err )
}
req . Header . Set ( "Content-Type" , "application/json" )
req . Header . Set ( "Accept-Encoding" , "" )
client := & http . Client { }
resp , err := client . Do ( req )
if err != nil {
panic ( err )
}
if ce := resp . Header . Get ( "Content-Encoding" ) ; ce == "gzip" {
t . Fatalf ( "unexpected Content-Encoding. expected %q, actual: %q" , "" , ce )
}
}
2015-02-20 01:55:42 +00:00
2015-02-20 00:51:14 +00:00
func TestHandler_Index ( t * testing . T ) {
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
s := NewHTTPServer ( srvr )
defer s . Close ( )
status , body := MustHTTP ( "GET" , s . URL , nil , nil , "" )
if status != http . StatusOK {
t . Fatalf ( "unexpected status: %d" , status )
}
if body != "1" {
t . Fatalf ( "unexpected body. expected %q, actual %q" , "1" , body )
}
}
2015-02-20 02:34:52 +00:00
func TestHandler_Wait ( t * testing . T ) {
2015-02-20 02:41:08 +00:00
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
s := NewHTTPServer ( srvr )
defer s . Close ( )
status , body := MustHTTP ( "GET" , s . URL + ` /wait/1 ` , map [ string ] string { "timeout" : "1" } , nil , "" )
if status != http . StatusOK {
t . Fatalf ( "unexpected status: %d" , status )
}
if body != "1" {
t . Fatalf ( "unexpected body. expected %q, actual %q" , "1" , body )
}
}
func TestHandler_WaitIncrement ( t * testing . T ) {
2015-02-20 00:51:14 +00:00
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
2015-02-20 02:34:52 +00:00
srvr . CreateDatabase ( "foo" )
srvr . CreateRetentionPolicy ( "foo" , influxdb . NewRetentionPolicy ( "bar" ) )
2015-02-20 00:51:14 +00:00
s := NewHTTPServer ( srvr )
defer s . Close ( )
2015-02-20 02:34:52 +00:00
status , _ := MustHTTP ( "GET" , s . URL + ` /wait/2 ` , map [ string ] string { "timeout" : "200" } , nil , "" )
// Write some data
2015-02-23 22:37:10 +00:00
_ , _ = MustHTTP ( "POST" , s . URL + ` /write ` , nil , nil , ` { "database" : "foo", "retentionPolicy" : "bar", "points": [ { "name": "cpu", "tags": { "host": "server01"},"timestamp": "2009-11-10T23:00:00Z","fields": { "value": 100}}]} ` )
2015-02-20 00:51:14 +00:00
if status != http . StatusOK {
2015-02-20 02:34:52 +00:00
t . Fatalf ( "unexpected status, expected: %d, actual: %d" , http . StatusOK , status )
2015-02-20 00:51:14 +00:00
}
2015-02-20 02:34:52 +00:00
}
2015-02-20 00:51:14 +00:00
2015-02-20 02:34:52 +00:00
func TestHandler_WaitNoIndexSpecified ( t * testing . T ) {
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
s := NewHTTPServer ( srvr )
defer s . Close ( )
2015-02-20 00:51:14 +00:00
2015-02-20 02:34:52 +00:00
status , _ := MustHTTP ( "GET" , s . URL + ` /wait ` , nil , nil , "" )
if status != http . StatusNotFound {
t . Fatalf ( "unexpected status, expected: %d, actual: %d" , http . StatusNotFound , status )
2015-02-20 00:51:14 +00:00
}
}
2015-02-05 00:51:10 +00:00
2015-02-20 02:34:52 +00:00
func TestHandler_WaitInvalidIndexSpecified ( t * testing . T ) {
2015-02-20 01:55:42 +00:00
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
s := NewHTTPServer ( srvr )
defer s . Close ( )
2015-02-20 02:34:52 +00:00
status , _ := MustHTTP ( "GET" , s . URL + ` /wait/foo ` , nil , nil , "" )
2015-02-20 01:55:42 +00:00
2015-02-20 02:34:52 +00:00
if status != http . StatusBadRequest {
t . Fatalf ( "unexpected status, expected: %d, actual: %d" , http . StatusBadRequest , status )
2015-02-20 01:55:42 +00:00
}
}
2015-02-20 02:34:52 +00:00
func TestHandler_WaitExpectTimeout ( t * testing . T ) {
2015-02-20 01:55:42 +00:00
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
s := NewHTTPServer ( srvr )
defer s . Close ( )
2015-02-20 02:34:52 +00:00
status , _ := MustHTTP ( "GET" , s . URL + ` /wait/2 ` , map [ string ] string { "timeout" : "1" } , nil , "" )
2015-02-20 01:55:42 +00:00
if status != http . StatusRequestTimeout {
t . Fatalf ( "unexpected status, expected: %d, actual: %d" , http . StatusRequestTimeout , status )
}
}
2014-11-20 23:50:15 +00:00
func TestHandler_Ping ( t * testing . T ) {
2015-02-05 22:54:32 +00:00
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
2014-11-20 23:50:15 +00:00
s := NewHTTPServer ( srvr )
defer s . Close ( )
2014-12-21 17:45:50 +00:00
2015-01-13 18:55:40 +00:00
status , _ := MustHTTP ( "GET" , s . URL + ` /ping ` , nil , nil , "" )
2014-12-21 17:45:50 +00:00
2015-02-13 00:46:39 +00:00
if status != http . StatusNoContent {
t . Fatalf ( "unexpected status: %d" , status )
}
}
func TestHandler_PingHead ( t * testing . T ) {
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
s := NewHTTPServer ( srvr )
defer s . Close ( )
status , _ := MustHTTP ( "HEAD" , s . URL + ` /ping ` , nil , nil , "" )
2015-01-22 20:54:19 +00:00
if status != http . StatusNoContent {
2014-11-20 23:50:15 +00:00
t . Fatalf ( "unexpected status: %d" , status )
}
}
2014-12-08 18:39:33 +00:00
func TestHandler_Users_NoUsers ( t * testing . T ) {
2015-02-05 22:54:32 +00:00
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
2014-12-08 18:39:33 +00:00
srvr . CreateDatabase ( "foo" )
s := NewHTTPServer ( srvr )
defer s . Close ( )
2014-12-21 17:45:50 +00:00
2015-01-27 03:11:48 +00:00
query := map [ string ] string { "q" : "SHOW USERS" }
status , body := MustHTTP ( "GET" , s . URL + ` /query ` , query , nil , "" )
2014-12-08 18:39:33 +00:00
if status != http . StatusOK {
t . Fatalf ( "unexpected status: %d" , status )
2015-02-23 05:21:49 +00:00
} else if body != ` { "results":[ { "series":[ { "columns":["user","admin"]}]}]} ` {
2014-12-08 18:39:33 +00:00
t . Fatalf ( "unexpected body: %s" , body )
}
}
func TestHandler_Users_OneUser ( t * testing . T ) {
2015-02-05 22:54:32 +00:00
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
2014-12-23 06:18:05 +00:00
srvr . CreateUser ( "jdoe" , "1337" , true )
2014-12-08 18:39:33 +00:00
s := NewHTTPServer ( srvr )
defer s . Close ( )
2014-12-21 17:45:50 +00:00
2015-01-27 03:11:48 +00:00
query := map [ string ] string { "q" : "SHOW USERS" }
status , body := MustHTTP ( "GET" , s . URL + ` /query ` , query , nil , "" )
2014-12-08 18:39:33 +00:00
if status != http . StatusOK {
t . Fatalf ( "unexpected status: %d" , status )
2015-02-23 05:21:49 +00:00
} else if body != ` { "results":[ { "series":[ { "columns":["user","admin"],"values":[["jdoe",true]]}]}]} ` {
2014-12-08 18:39:33 +00:00
t . Fatalf ( "unexpected body: %s" , body )
}
}
func TestHandler_Users_MultipleUsers ( t * testing . T ) {
2015-02-05 22:54:32 +00:00
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
2014-12-23 06:18:05 +00:00
srvr . CreateUser ( "jdoe" , "1337" , false )
srvr . CreateUser ( "mclark" , "1337" , true )
srvr . CreateUser ( "csmith" , "1337" , false )
2014-12-08 18:39:33 +00:00
s := NewHTTPServer ( srvr )
defer s . Close ( )
2014-12-21 17:45:50 +00:00
2015-01-27 03:11:48 +00:00
query := map [ string ] string { "q" : "SHOW USERS" }
status , body := MustHTTP ( "GET" , s . URL + ` /query ` , query , nil , "" )
2014-12-08 18:39:33 +00:00
if status != http . StatusOK {
t . Fatalf ( "unexpected status: %d" , status )
2015-02-23 05:21:49 +00:00
} else if body != ` { "results":[ { "series":[ { "columns":["user","admin"],"values":[["csmith",false],["jdoe",false],["mclark",true]]}]}]} ` {
2014-12-08 18:39:33 +00:00
t . Fatalf ( "unexpected body: %s" , body )
}
}
2014-12-23 06:18:05 +00:00
func TestHandler_CreateUser ( t * testing . T ) {
2015-02-05 22:54:32 +00:00
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
2014-11-26 14:36:43 +00:00
s := NewHTTPServer ( srvr )
defer s . Close ( )
2015-01-19 20:01:32 +00:00
query := map [ string ] string { "q" : ` CREATE USER testuser WITH PASSWORD '1337' ` }
2015-01-14 05:52:46 +00:00
status , body := MustHTTP ( "GET" , s . URL + ` /query ` , query , nil , "" )
2015-01-14 19:45:07 +00:00
if status != http . StatusOK {
2014-11-26 14:36:43 +00:00
t . Fatalf ( "unexpected status: %d" , status )
2015-01-27 20:27:29 +00:00
} else if body != ` { "results":[ { }]} ` {
2014-11-26 14:36:43 +00:00
t . Fatalf ( "unexpected body: %s" , body )
}
}
2014-12-23 06:18:05 +00:00
func TestHandler_CreateUser_BadRequest ( t * testing . T ) {
2015-02-05 22:54:32 +00:00
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
2014-11-26 14:36:43 +00:00
s := NewHTTPServer ( srvr )
defer s . Close ( )
2015-01-14 05:52:46 +00:00
query := map [ string ] string { "q" : "CREATE USER 0xBAD WITH PASSWORD pwd1337" }
status , body := MustHTTP ( "GET" , s . URL + ` /query ` , query , nil , "" )
2014-11-26 14:36:43 +00:00
if status != http . StatusBadRequest {
t . Fatalf ( "unexpected status: %d" , status )
2015-01-27 20:27:29 +00:00
} else if body != ` { "error":"error parsing query: found 0, expected identifier at line 1, char 13"} ` {
2014-11-26 14:36:43 +00:00
t . Fatalf ( "unexpected body: %s" , body )
}
}
2015-01-14 05:52:46 +00:00
func TestHandler_CreateUser_BadRequest_NoName ( t * testing . T ) {
2015-02-05 22:54:32 +00:00
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
2014-11-26 14:36:43 +00:00
s := NewHTTPServer ( srvr )
defer s . Close ( )
2015-01-14 05:52:46 +00:00
query := map [ string ] string { "q" : "CREATE USER WITH PASSWORD pwd1337" }
status , body := MustHTTP ( "GET" , s . URL + ` /query ` , query , nil , "" )
if status != http . StatusBadRequest {
t . Fatalf ( "unexpected status: %d" , status )
2015-01-27 20:27:29 +00:00
} else if body != ` { "error":"error parsing query: found WITH, expected identifier at line 1, char 13"} ` {
2015-01-14 05:52:46 +00:00
t . Fatalf ( "unexpected body: %s" , body )
}
}
func TestHandler_CreateUser_BadRequest_NoPassword ( t * testing . T ) {
2015-02-05 22:54:32 +00:00
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
2015-01-14 05:52:46 +00:00
s := NewHTTPServer ( srvr )
defer s . Close ( )
query := map [ string ] string { "q" : "CREATE USER jdoe" }
status , body := MustHTTP ( "GET" , s . URL + ` /query ` , query , nil , "" )
if status != http . StatusBadRequest {
2014-11-26 16:02:17 +00:00
t . Fatalf ( "unexpected status: %d" , status )
2015-01-27 20:27:29 +00:00
} else if body != ` { "error":"error parsing query: found EOF, expected WITH at line 1, char 18"} ` {
2014-11-26 16:02:17 +00:00
t . Fatalf ( "unexpected body: %s" , body )
}
}
2014-12-23 06:18:05 +00:00
func TestHandler_UpdateUser ( t * testing . T ) {
2015-01-09 04:58:33 +00:00
t . Skip ( )
2015-02-05 22:54:32 +00:00
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
2014-12-23 06:18:05 +00:00
srvr . CreateUser ( "jdoe" , "1337" , false )
2014-11-26 22:10:56 +00:00
s := NewHTTPServer ( srvr )
defer s . Close ( )
2014-12-21 17:45:50 +00:00
2014-12-23 06:18:05 +00:00
// Save original password hash.
hash := srvr . User ( "jdoe" ) . Hash
2014-12-21 17:45:50 +00:00
2014-12-23 06:18:05 +00:00
// Update user password.
2015-01-13 18:55:40 +00:00
status , body := MustHTTP ( "PUT" , s . URL + ` /users/jdoe ` , nil , nil , ` { "password": "7331"} ` )
2015-01-14 19:45:07 +00:00
if status != http . StatusOK {
2014-11-26 22:10:56 +00:00
t . Fatalf ( "unexpected status: %d" , status )
} else if body != ` ` {
t . Fatalf ( "unexpected body: %s" , body )
2014-12-23 06:18:05 +00:00
} else if srvr . User ( "jdoe" ) . Hash == hash {
2014-11-26 22:10:56 +00:00
t . Fatalf ( "expected password hash to change" )
}
}
2014-12-23 06:18:05 +00:00
func TestHandler_UpdateUser_PasswordBadRequest ( t * testing . T ) {
2015-01-09 04:58:33 +00:00
t . Skip ( )
2015-02-05 22:54:32 +00:00
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
2014-12-23 06:18:05 +00:00
srvr . CreateUser ( "jdoe" , "1337" , false )
2014-11-26 22:10:56 +00:00
s := NewHTTPServer ( srvr )
defer s . Close ( )
2014-12-21 17:45:50 +00:00
2015-01-13 18:55:40 +00:00
status , body := MustHTTP ( "PUT" , s . URL + ` /users/jdoe ` , nil , nil , ` { "password": 10} ` )
2014-11-26 22:10:56 +00:00
if status != http . StatusBadRequest {
t . Fatalf ( "unexpected status: %d" , status )
2014-12-21 17:45:50 +00:00
} else if body != ` json: cannot unmarshal number into Go value of type string ` {
2014-11-26 22:10:56 +00:00
t . Fatalf ( "unexpected body: %s" , body )
}
}
2014-12-23 06:18:05 +00:00
func TestHandler_DeleteUser ( t * testing . T ) {
2015-02-05 22:54:32 +00:00
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
2014-12-23 06:18:05 +00:00
srvr . CreateUser ( "jdoe" , "1337" , false )
2014-11-26 22:10:56 +00:00
s := NewHTTPServer ( srvr )
defer s . Close ( )
2014-12-21 17:45:50 +00:00
2015-01-14 05:57:59 +00:00
query := map [ string ] string { "q" : "DROP USER jdoe" }
status , body := MustHTTP ( "GET" , s . URL + ` /query ` , query , nil , "" )
2015-01-14 19:45:07 +00:00
if status != http . StatusOK {
2014-12-05 18:31:12 +00:00
t . Fatalf ( "unexpected status: %d" , status )
2015-01-27 20:27:29 +00:00
} else if body != ` { "results":[ { }]} ` {
2014-12-05 18:31:12 +00:00
t . Fatalf ( "unexpected body: %s" , body )
}
}
2014-12-23 06:18:05 +00:00
func TestHandler_DeleteUser_UserNotFound ( t * testing . T ) {
2015-02-05 22:54:32 +00:00
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
2014-12-05 18:31:12 +00:00
s := NewHTTPServer ( srvr )
defer s . Close ( )
2014-12-21 17:45:50 +00:00
2015-01-14 05:57:59 +00:00
query := map [ string ] string { "q" : "DROP USER jdoe" }
status , body := MustHTTP ( "GET" , s . URL + ` /query ` , query , nil , "" )
if status != http . StatusInternalServerError {
2014-12-05 18:31:12 +00:00
t . Fatalf ( "unexpected status: %d" , status )
2015-01-27 20:27:29 +00:00
} else if body != ` { "results":[ { "error":"user not found"}]} ` {
2014-12-05 18:31:12 +00:00
t . Fatalf ( "unexpected body: %s" , body )
}
}
2014-12-30 15:50:15 +00:00
func TestHandler_DataNodes ( t * testing . T ) {
2015-01-09 04:58:33 +00:00
t . Skip ( )
2015-02-05 23:25:10 +00:00
srvr := OpenUninitializedServer ( NewMessagingClient ( ) )
2014-12-30 15:50:15 +00:00
srvr . CreateDataNode ( MustParseURL ( "http://localhost:1000" ) )
srvr . CreateDataNode ( MustParseURL ( "http://localhost:2000" ) )
srvr . CreateDataNode ( MustParseURL ( "http://localhost:3000" ) )
2014-12-29 23:12:51 +00:00
s := NewHTTPServer ( srvr )
defer s . Close ( )
2015-01-13 18:55:40 +00:00
status , body := MustHTTP ( "GET" , s . URL + ` /data_nodes ` , nil , nil , "" )
2014-12-29 23:12:51 +00:00
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 )
}
}
2014-12-30 15:50:15 +00:00
func TestHandler_CreateDataNode ( t * testing . T ) {
2015-01-09 04:58:33 +00:00
t . Skip ( )
2015-02-05 23:25:10 +00:00
srvr := OpenUninitializedServer ( NewMessagingClient ( ) )
2014-12-29 23:12:51 +00:00
s := NewHTTPServer ( srvr )
defer s . Close ( )
2015-01-13 18:55:40 +00:00
status , body := MustHTTP ( "POST" , s . URL + ` /data_nodes ` , nil , nil , ` { "url":"http://localhost:1000"} ` )
2015-01-14 19:45:07 +00:00
if status != http . StatusOK {
2014-12-29 23:12:51 +00:00
t . Fatalf ( "unexpected status: %d" , status )
} else if body != ` { "id":1,"url":"http://localhost:1000"} ` {
t . Fatalf ( "unexpected body: %s" , body )
}
}
2014-12-30 15:50:15 +00:00
func TestHandler_CreateDataNode_BadRequest ( t * testing . T ) {
2015-01-09 04:58:33 +00:00
t . Skip ( )
2015-02-05 22:54:32 +00:00
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
2014-12-29 23:12:51 +00:00
s := NewHTTPServer ( srvr )
defer s . Close ( )
2015-01-13 18:55:40 +00:00
status , body := MustHTTP ( "POST" , s . URL + ` /data_nodes ` , nil , nil , ` { "name": ` )
2014-12-29 23:12:51 +00:00
if status != http . StatusBadRequest {
t . Fatalf ( "unexpected status: %d" , status )
} else if body != ` unexpected EOF ` {
t . Fatalf ( "unexpected body: %s" , body )
}
}
2014-12-30 15:50:15 +00:00
func TestHandler_CreateDataNode_InternalServerError ( t * testing . T ) {
2015-01-09 04:58:33 +00:00
t . Skip ( )
2015-02-05 22:54:32 +00:00
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
2014-12-29 23:12:51 +00:00
s := NewHTTPServer ( srvr )
defer s . Close ( )
2015-01-13 18:55:40 +00:00
status , body := MustHTTP ( "POST" , s . URL + ` /data_nodes ` , nil , nil , ` { "url":""} ` )
2014-12-29 23:12:51 +00:00
if status != http . StatusInternalServerError {
2014-12-30 22:52:44 +00:00
t . Fatalf ( "unexpected status: %d, %s" , status , body )
2014-12-30 15:50:15 +00:00
} else if body != ` data node url required ` {
2014-12-29 23:12:51 +00:00
t . Fatalf ( "unexpected body: %s" , body )
}
}
2014-12-30 15:50:15 +00:00
func TestHandler_DeleteDataNode ( t * testing . T ) {
2015-01-09 04:58:33 +00:00
t . Skip ( )
2015-02-05 22:54:32 +00:00
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
2014-12-30 15:50:15 +00:00
srvr . CreateDataNode ( MustParseURL ( "http://localhost:1000" ) )
2014-12-29 23:12:51 +00:00
s := NewHTTPServer ( srvr )
defer s . Close ( )
2015-01-13 18:55:40 +00:00
status , body := MustHTTP ( "DELETE" , s . URL + ` /data_nodes/1 ` , nil , nil , "" )
2015-01-14 19:45:07 +00:00
if status != http . StatusOK {
2014-12-29 23:12:51 +00:00
t . Fatalf ( "unexpected status: %d" , status )
} else if body != ` ` {
t . Fatalf ( "unexpected body: %s" , body )
}
}
2014-12-30 15:50:15 +00:00
func TestHandler_DeleteUser_DataNodeNotFound ( t * testing . T ) {
2015-01-09 04:58:33 +00:00
t . Skip ( )
2015-02-05 22:54:32 +00:00
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
2014-12-29 23:12:51 +00:00
s := NewHTTPServer ( srvr )
defer s . Close ( )
2015-01-13 18:55:40 +00:00
status , body := MustHTTP ( "DELETE" , s . URL + ` /data_nodes/10000 ` , nil , nil , "" )
2014-12-29 23:12:51 +00:00
if status != http . StatusNotFound {
t . Fatalf ( "unexpected status: %d" , status )
2014-12-30 15:50:15 +00:00
} else if body != ` data node not found ` {
2014-12-29 23:12:51 +00:00
t . Fatalf ( "unexpected body: %s" , body )
}
}
2015-01-05 23:47:12 +00:00
// Perform a subset of endpoint testing, with authentication enabled.
func TestHandler_AuthenticatedCreateAdminUser ( t * testing . T ) {
2015-02-05 22:54:32 +00:00
srvr := OpenAuthenticatedServer ( NewMessagingClient ( ) )
2015-01-05 23:47:12 +00:00
s := NewAuthenticatedHTTPServer ( srvr )
defer s . Close ( )
// Attempting to create a non-admin user should fail.
2015-01-21 19:29:51 +00:00
query := map [ string ] string { "q" : "CREATE USER maeve WITH PASSWORD 'pass'" }
2015-01-14 06:45:03 +00:00
status , _ := MustHTTP ( "GET" , s . URL + ` /query ` , query , nil , "" )
2015-01-05 23:47:12 +00:00
if status != http . StatusUnauthorized {
t . Fatalf ( "unexpected status: %d" , status )
}
2015-02-05 21:04:28 +00:00
// Creating an admin user, without supplying authentication credentials should fail.
2015-01-21 19:29:51 +00:00
query = map [ string ] string { "q" : "CREATE USER louise WITH PASSWORD 'pass' WITH ALL PRIVILEGES" }
2015-01-14 06:45:03 +00:00
status , _ = MustHTTP ( "GET" , s . URL + ` /query ` , query , nil , "" )
2015-01-05 23:47:12 +00:00
if status != http . StatusUnauthorized {
t . Fatalf ( "unexpected status: %d" , status )
}
}
func TestHandler_AuthenticatedDatabases_Unauthorized ( t * testing . T ) {
2015-02-05 22:54:32 +00:00
srvr := OpenAuthenticatedServer ( NewMessagingClient ( ) )
2015-01-05 23:47:12 +00:00
s := NewAuthenticatedHTTPServer ( srvr )
defer s . Close ( )
2015-01-26 16:28:08 +00:00
status , _ := MustHTTP ( "GET" , s . URL + ` /query ` , map [ string ] string { "q" : "SHOW DATABASES" } , nil , "" )
2015-01-05 23:47:12 +00:00
if status != http . StatusUnauthorized {
t . Fatalf ( "unexpected status: %d" , status )
}
}
func TestHandler_AuthenticatedDatabases_AuthorizedQueryParams ( t * testing . T ) {
2015-02-05 22:54:32 +00:00
srvr := OpenAuthenticatedServer ( NewMessagingClient ( ) )
2015-01-05 23:47:12 +00:00
srvr . CreateUser ( "lisa" , "password" , true )
s := NewAuthenticatedHTTPServer ( srvr )
defer s . Close ( )
2015-01-26 16:28:08 +00:00
query := map [ string ] string { "q" : "SHOW DATABASES" , "u" : "lisa" , "p" : "password" }
2015-01-14 06:45:03 +00:00
status , _ := MustHTTP ( "GET" , s . URL + ` /query ` , query , nil , "" )
2015-01-05 23:47:12 +00:00
if status != http . StatusOK {
t . Fatalf ( "unexpected status: %d" , status )
}
}
2015-01-14 06:45:03 +00:00
func TestHandler_AuthenticatedDatabases_UnauthorizedQueryParams ( t * testing . T ) {
2015-02-05 22:54:32 +00:00
srvr := OpenAuthenticatedServer ( NewMessagingClient ( ) )
2015-01-14 06:45:03 +00:00
srvr . CreateUser ( "lisa" , "password" , true )
s := NewAuthenticatedHTTPServer ( srvr )
defer s . Close ( )
2015-01-26 16:28:08 +00:00
query := map [ string ] string { "q" : "SHOW DATABASES" , "u" : "lisa" , "p" : "wrong" }
2015-01-14 06:45:03 +00:00
status , _ := MustHTTP ( "GET" , s . URL + ` /query ` , query , nil , "" )
if status != http . StatusUnauthorized {
t . Fatalf ( "unexpected status: %d" , status )
}
}
2015-01-05 23:47:12 +00:00
func TestHandler_AuthenticatedDatabases_AuthorizedBasicAuth ( t * testing . T ) {
2015-02-05 22:54:32 +00:00
srvr := OpenAuthenticatedServer ( NewMessagingClient ( ) )
2015-01-05 23:47:12 +00:00
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" ) )
2015-01-26 16:28:08 +00:00
query := map [ string ] string { "q" : "SHOW DATABASES" }
2015-01-14 06:45:03 +00:00
status , _ := MustHTTP ( "GET" , s . URL + ` /query ` , query , auth , "" )
2015-01-05 23:47:12 +00:00
if status != http . StatusOK {
t . Fatalf ( "unexpected status: %d" , status )
}
}
2015-01-14 06:45:03 +00:00
func TestHandler_AuthenticatedDatabases_UnauthorizedBasicAuth ( t * testing . T ) {
2015-02-05 22:54:32 +00:00
srvr := OpenAuthenticatedServer ( NewMessagingClient ( ) )
2015-01-14 06:45:03 +00:00
srvr . CreateUser ( "lisa" , "password" , true )
s := NewAuthenticatedHTTPServer ( srvr )
defer s . Close ( )
auth := make ( map [ string ] string )
auth [ "Authorization" ] = "Basic " + base64 . StdEncoding . EncodeToString ( [ ] byte ( "lisa:wrong" ) )
2015-01-26 16:28:08 +00:00
query := map [ string ] string { "q" : "SHOW DATABASES" }
2015-01-14 06:45:03 +00:00
status , _ := MustHTTP ( "GET" , s . URL + ` /query ` , query , auth , "" )
if status != http . StatusUnauthorized {
t . Fatalf ( "unexpected status: %d" , status )
}
}
2015-01-30 02:26:28 +00:00
func TestHandler_GrantAdmin ( t * testing . T ) {
2015-02-05 22:54:32 +00:00
srvr := OpenAuthenticatedServer ( NewMessagingClient ( ) )
2015-01-30 02:26:28 +00:00
// Create a cluster admin that will grant admin to "john".
srvr . CreateUser ( "lisa" , "password" , true )
// Create user that will be granted cluster admin.
srvr . CreateUser ( "john" , "password" , false )
s := NewAuthenticatedHTTPServer ( srvr )
defer s . Close ( )
auth := make ( map [ string ] string )
auth [ "Authorization" ] = "Basic " + base64 . StdEncoding . EncodeToString ( [ ] byte ( "lisa:password" ) )
query := map [ string ] string { "q" : "GRANT ALL PRIVILEGES TO john" }
status , _ := MustHTTP ( "GET" , s . URL + ` /query ` , query , auth , "" )
if status != http . StatusOK {
t . Fatalf ( "unexpected status: %d" , status )
}
if u := srvr . User ( "john" ) ; ! u . Admin {
t . Fatal ( ` expected user "john" to be admin ` )
}
2015-01-30 15:43:29 +00:00
// Make sure update persists after server restart.
srvr . Restart ( )
if u := srvr . User ( "john" ) ; ! u . Admin {
t . Fatal ( ` expected user "john" to be admin after server restart ` )
}
2015-01-30 02:26:28 +00:00
}
2015-01-30 03:02:58 +00:00
func TestHandler_GrantDBPrivilege ( t * testing . T ) {
2015-02-05 22:54:32 +00:00
srvr := OpenAuthenticatedServer ( NewMessagingClient ( ) )
2015-01-30 03:02:58 +00:00
// Create a cluster admin that will grant privilege to "john".
srvr . CreateUser ( "lisa" , "password" , true )
// Create user that will be granted a privilege.
srvr . CreateUser ( "john" , "password" , false )
s := NewAuthenticatedHTTPServer ( srvr )
defer s . Close ( )
auth := make ( map [ string ] string )
auth [ "Authorization" ] = "Basic " + base64 . StdEncoding . EncodeToString ( [ ] byte ( "lisa:password" ) )
query := map [ string ] string { "q" : "GRANT READ ON foo TO john" }
status , _ := MustHTTP ( "GET" , s . URL + ` /query ` , query , auth , "" )
if status != http . StatusOK {
t . Fatalf ( "unexpected status: %d" , status )
}
u := srvr . User ( "john" )
if p , ok := u . Privileges [ "foo" ] ; ! ok {
t . Fatal ( ` expected john to have privileges on foo but he has none ` )
} else if p != influxql . ReadPrivilege {
t . Fatalf ( ` expected john to have read privilege on foo but he has %s ` , p . String ( ) )
}
2015-01-30 15:43:29 +00:00
// Make sure update persists after server restart.
srvr . Restart ( )
u = srvr . User ( "john" )
if p , ok := u . Privileges [ "foo" ] ; ! ok {
t . Fatal ( ` expected john to have privileges on foo but he has none after restart ` )
} else if p != influxql . ReadPrivilege {
t . Fatalf ( ` expected john to have read privilege on foo but he has %s after restart ` , p . String ( ) )
}
2015-01-30 03:02:58 +00:00
}
2015-01-30 02:56:23 +00:00
func TestHandler_RevokeAdmin ( t * testing . T ) {
2015-02-05 22:54:32 +00:00
srvr := OpenAuthenticatedServer ( NewMessagingClient ( ) )
2015-01-30 02:56:23 +00:00
// Create a cluster admin that will revoke admin from "john".
srvr . CreateUser ( "lisa" , "password" , true )
// Create user that will have cluster admin revoked.
srvr . CreateUser ( "john" , "password" , true )
s := NewAuthenticatedHTTPServer ( srvr )
defer s . Close ( )
auth := make ( map [ string ] string )
auth [ "Authorization" ] = "Basic " + base64 . StdEncoding . EncodeToString ( [ ] byte ( "lisa:password" ) )
query := map [ string ] string { "q" : "REVOKE ALL PRIVILEGES FROM john" }
status , body := MustHTTP ( "GET" , s . URL + ` /query ` , query , auth , "" )
if status != http . StatusOK {
t . Log ( body )
t . Fatalf ( "unexpected status: %d" , status )
}
if u := srvr . User ( "john" ) ; u . Admin {
t . Fatal ( ` expected user "john" not to be admin ` )
}
2015-01-30 15:43:29 +00:00
// Make sure update persists after server restart.
srvr . Restart ( )
if u := srvr . User ( "john" ) ; u . Admin {
t . Fatal ( ` expected user "john" not to be admin after restart ` )
}
2015-01-30 02:56:23 +00:00
}
func TestHandler_RevokeDBPrivilege ( t * testing . T ) {
2015-02-05 22:54:32 +00:00
srvr := OpenAuthenticatedServer ( NewMessagingClient ( ) )
2015-01-30 02:56:23 +00:00
// Create a cluster admin that will revoke privilege from "john".
srvr . CreateUser ( "lisa" , "password" , true )
// Create user that will have privilege revoked.
srvr . CreateUser ( "john" , "password" , false )
u := srvr . User ( "john" )
u . Privileges [ "foo" ] = influxql . ReadPrivilege
s := NewAuthenticatedHTTPServer ( srvr )
defer s . Close ( )
auth := make ( map [ string ] string )
auth [ "Authorization" ] = "Basic " + base64 . StdEncoding . EncodeToString ( [ ] byte ( "lisa:password" ) )
query := map [ string ] string { "q" : "REVOKE READ ON foo FROM john" }
status , body := MustHTTP ( "GET" , s . URL + ` /query ` , query , auth , "" )
if status != http . StatusOK {
t . Log ( body )
t . Fatalf ( "unexpected status: %d" , status )
}
2015-01-30 15:43:29 +00:00
if p := u . Privileges [ "foo" ] ; p != influxql . NoPrivileges {
2015-01-30 02:56:23 +00:00
t . Fatal ( ` expected user "john" not to have privileges on foo ` )
}
2015-01-30 15:43:29 +00:00
// Make sure update persists after server restart.
srvr . Restart ( )
if p := u . Privileges [ "foo" ] ; p != influxql . NoPrivileges {
t . Fatal ( ` expected user "john" not to have privileges on foo after restart ` )
}
2015-01-30 02:56:23 +00:00
}
2015-02-09 08:58:41 +00:00
func TestHandler_ShowContinuousQueries ( t * testing . T ) {
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
srvr . CreateDatabase ( "foo" )
srvr . CreateRetentionPolicy ( "foo" , influxdb . NewRetentionPolicy ( "bar" ) )
srvr . SetDefaultRetentionPolicy ( "foo" , "bar" )
// create and check
q := "CREATE CONTINUOUS QUERY myquery ON foo BEGIN SELECT count() INTO measure1 FROM myseries GROUP BY time(10m) END"
stmt , err := influxql . NewParser ( strings . NewReader ( q ) ) . ParseStatement ( )
if err != nil {
t . Fatalf ( "error parsing query %s" , err . Error ( ) )
}
cq := stmt . ( * influxql . CreateContinuousQueryStatement )
if err := srvr . CreateContinuousQuery ( cq ) ; err != nil {
t . Fatalf ( "error creating continuous query %s" , err . Error ( ) )
}
s := NewHTTPServer ( srvr )
defer s . Close ( )
query := map [ string ] string { "q" : "SHOW CONTINUOUS QUERIES" }
status , body := MustHTTP ( "GET" , s . URL + ` /query ` , query , nil , "" )
if status != http . StatusOK {
t . Fatalf ( "unexpected status: %d" , status )
2015-02-23 05:21:49 +00:00
} else if body != ` { "results":[ { "series":[ { "name":"foo","columns":["name","query"],"values":[["myquery","CREATE CONTINUOUS QUERY myquery ON foo BEGIN SELECT count() INTO measure1 FROM myseries GROUP BY time(10m) END"]]}]}]} ` {
2015-02-09 08:58:41 +00:00
t . Fatalf ( "unexpected body: %s" , body )
}
}
2015-02-20 22:06:22 +00:00
func TestHandler_DropSeries ( t * testing . T ) {
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
srvr . CreateDatabase ( "foo" )
srvr . CreateRetentionPolicy ( "foo" , influxdb . NewRetentionPolicy ( "bar" ) )
s := NewHTTPServer ( srvr )
defer s . Close ( )
2015-02-23 22:37:10 +00:00
status , _ := MustHTTP ( "POST" , s . URL + ` /write ` , nil , nil , ` { "database" : "foo", "retentionPolicy" : "bar", "points": [ { "name": "cpu", "tags": { "host": "server01"},"timestamp": "2009-11-10T23:00:00Z","fields": { "value": 100}}]} ` )
2015-02-20 22:06:22 +00:00
if status != http . StatusOK {
t . Fatalf ( "unexpected status: %d" , status )
}
query := map [ string ] string { "db" : "foo" , "q" : "DROP SERIES FROM cpu" }
status , _ = MustHTTP ( "GET" , s . URL + ` /query ` , query , nil , "" )
if status != http . StatusOK {
t . Fatalf ( "unexpected status: %d" , status )
}
}
2015-01-14 21:08:53 +00:00
func TestHandler_serveWriteSeries ( t * testing . T ) {
2015-02-05 22:54:32 +00:00
srvr := OpenAuthenticatedServer ( NewMessagingClient ( ) )
2015-01-14 21:08:53 +00:00
srvr . CreateDatabase ( "foo" )
srvr . CreateRetentionPolicy ( "foo" , influxdb . NewRetentionPolicy ( "bar" ) )
s := NewHTTPServer ( srvr )
defer s . Close ( )
2015-02-23 22:37:10 +00:00
status , _ := MustHTTP ( "POST" , s . URL + ` /write ` , nil , nil , ` { "database" : "foo", "retentionPolicy" : "bar", "points": [ { "name": "cpu", "tags": { "host": "server01"},"timestamp": "2009-11-10T23:00:00Z","fields": { "value": 100}}]} ` )
2015-01-14 21:08:53 +00:00
if status != http . StatusOK {
t . Fatalf ( "unexpected status: %d" , status )
}
}
2015-02-24 19:09:10 +00:00
func TestHandler_serveWriteSeriesWithNoFields ( t * testing . T ) {
srvr := OpenAuthenticatedServer ( NewMessagingClient ( ) )
srvr . CreateDatabase ( "foo" )
srvr . CreateRetentionPolicy ( "foo" , influxdb . NewRetentionPolicy ( "bar" ) )
s := NewHTTPServer ( srvr )
defer s . Close ( )
status , body := MustHTTP ( "POST" , s . URL + ` /write ` , nil , nil , ` { "database" : "foo", "retentionPolicy" : "bar", "points": [ { "name": "cpu", "tags": { "host": "server01"},"timestamp": "2009-11-10T23:00:00Z"}]} ` )
expected := ` { "error":"point cpu has no fields"} `
if status != http . StatusInternalServerError {
t . Fatalf ( "unexpected status: %d" , status )
} else if body != expected {
t . Fatalf ( "result mismatch:\n\texp=%s\n\tgot=%s\n" , expected , body )
}
}
2015-02-11 18:13:41 +00:00
func TestHandler_serveWriteSeriesWithAuthNilUser ( t * testing . T ) {
srvr := OpenAuthenticatedServer ( NewMessagingClient ( ) )
srvr . CreateDatabase ( "foo" )
srvr . CreateRetentionPolicy ( "foo" , influxdb . NewRetentionPolicy ( "bar" ) )
s := NewAuthenticatedHTTPServer ( srvr )
defer s . Close ( )
2015-02-23 22:37:10 +00:00
status , body := MustHTTP ( "POST" , s . URL + ` /write ` , nil , nil , ` { "database" : "foo", "retentionPolicy" : "bar", "points": [ { "name": "cpu", "tags": { "host": "server01"},"timestamp": "2009-11-10T23:00:00Z","fields": { "value": 100}}]} ` )
2015-02-11 18:13:41 +00:00
if status != http . StatusUnauthorized {
t . Fatalf ( "unexpected status: %d" , status )
}
response := ` { "error":"user is required to write to database \"foo\""} `
if body != response {
t . Fatalf ( "unexpected body: expected %s, actual %s" , response , body )
}
}
2015-01-15 21:58:21 +00:00
func TestHandler_serveWriteSeries_noDatabaseExists ( t * testing . T ) {
2015-02-05 22:54:32 +00:00
srvr := OpenAuthenticatedServer ( NewMessagingClient ( ) )
2015-01-15 20:09:52 +00:00
s := NewHTTPServer ( srvr )
defer s . Close ( )
2015-02-23 22:37:10 +00:00
status , body := MustHTTP ( "POST" , s . URL + ` /write ` , nil , nil , ` { "database" : "foo", "retentionPolicy" : "bar", "points": [ { "name": "cpu", "tags": { "host": "server01"},"timestamp": "2009-11-10T23:00:00Z","fields": { "value": 100}}]} ` )
2015-01-15 20:09:52 +00:00
2015-01-15 21:58:21 +00:00
expectedStatus := http . StatusNotFound
if status != expectedStatus {
t . Fatalf ( "unexpected status: expected: %d, actual: %d" , expectedStatus , status )
2015-01-15 20:09:52 +00:00
}
2015-01-15 21:58:21 +00:00
response := ` { "error":"database not found: \"foo\""} `
2015-01-15 20:09:52 +00:00
if body != response {
t . Fatalf ( "unexpected body: expected %s, actual %s" , response , body )
}
}
func TestHandler_serveWriteSeries_invalidJSON ( t * testing . T ) {
2015-02-05 22:54:32 +00:00
srvr := OpenAuthenticatedServer ( NewMessagingClient ( ) )
2015-01-15 20:09:52 +00:00
s := NewHTTPServer ( srvr )
defer s . Close ( )
2015-02-23 22:37:10 +00:00
status , body := MustHTTP ( "POST" , s . URL + ` /write ` , nil , nil , ` { "database" : foo", "retentionPolicy" : "bar", "points": [ { "name": "cpu", "tags": { "host": "server01"},"timestamp": "2009-11-10T23:00:00Z","fields": { "value": 100}}]} ` )
2015-01-15 20:09:52 +00:00
if status != http . StatusInternalServerError {
t . Fatalf ( "unexpected status: expected: %d, actual: %d" , http . StatusInternalServerError , status )
}
response := ` { "error":"invalid character 'o' in literal false (expecting 'a')"} `
if body != response {
t . Fatalf ( "unexpected body: expected %s, actual %s" , response , body )
}
}
2015-01-15 21:58:21 +00:00
func TestHandler_serveWriteSeries_noDatabaseSpecified ( t * testing . T ) {
2015-02-05 22:54:32 +00:00
srvr := OpenAuthenticatedServer ( NewMessagingClient ( ) )
2015-01-15 21:42:38 +00:00
s := NewHTTPServer ( srvr )
defer s . Close ( )
status , body := MustHTTP ( "POST" , s . URL + ` /write ` , nil , nil , ` { } ` )
if status != http . StatusInternalServerError {
t . Fatalf ( "unexpected status: expected: %d, actual: %d" , http . StatusInternalServerError , status )
}
2015-01-15 21:58:21 +00:00
response := ` { "error":"database is required"} `
2015-01-15 21:42:38 +00:00
if body != response {
t . Fatalf ( "unexpected body: expected %s, actual %s" , response , body )
}
}
2015-02-15 20:10:02 +00:00
func TestHandler_serveWriteSeriesNonZeroTime ( t * testing . T ) {
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
srvr . CreateDatabase ( "foo" )
srvr . CreateRetentionPolicy ( "foo" , influxdb . NewRetentionPolicy ( "bar" ) )
srvr . SetDefaultRetentionPolicy ( "foo" , "bar" )
s := NewHTTPServer ( srvr )
defer s . Close ( )
2015-02-23 22:37:10 +00:00
status , _ := MustHTTP ( "POST" , s . URL + ` /write ` , nil , nil , ` { "database" : "foo", "retentionPolicy" : "bar", "points": [ { "name": "cpu", "tags": { "host": "server01"},"timestamp": "2009-11-10T23:00:00Z", "fields": { "value": 100}}]} ` )
2015-02-15 20:10:02 +00:00
if status != http . StatusOK {
t . Fatalf ( "unexpected status: %d" , status )
}
2015-02-15 20:22:58 +00:00
time . Sleep ( 100 * time . Millisecond ) // Ensure data node picks up write.
2015-02-15 20:10:02 +00:00
2015-02-19 21:22:04 +00:00
srvr . Restart ( ) // Ensure data is queryable across restarts.
2015-02-15 20:10:02 +00:00
query := map [ string ] string { "db" : "foo" , "q" : "select value from cpu" }
status , body := MustHTTP ( "GET" , s . URL + ` /query ` , query , nil , "" )
if status != http . StatusOK {
t . Logf ( "query %s\n" , query )
t . Log ( body )
t . Errorf ( "unexpected status: %d" , status )
}
r := & influxdb . Results { }
if err := json . Unmarshal ( [ ] byte ( body ) , r ) ; err != nil {
t . Logf ( "query : %s\n" , query )
t . Log ( body )
t . Error ( err )
}
if len ( r . Results ) != 1 {
t . Fatalf ( "unexpected results count" )
}
result := r . Results [ 0 ]
2015-02-23 05:21:49 +00:00
if len ( result . Series ) != 1 {
t . Fatalf ( "unexpected row count, expected: %d, actual: %d" , 1 , len ( result . Series ) )
2015-02-15 20:10:02 +00:00
}
}
2015-02-10 22:57:46 +00:00
func TestHandler_serveWriteSeriesZeroTime ( t * testing . T ) {
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
srvr . CreateDatabase ( "foo" )
srvr . CreateRetentionPolicy ( "foo" , influxdb . NewRetentionPolicy ( "bar" ) )
srvr . SetDefaultRetentionPolicy ( "foo" , "bar" )
s := NewHTTPServer ( srvr )
defer s . Close ( )
now := time . Now ( )
2015-02-23 22:37:10 +00:00
status , _ := MustHTTP ( "POST" , s . URL + ` /write ` , nil , nil , ` { "database" : "foo", "retentionPolicy" : "bar", "points": [ { "name": "cpu", "tags": { "host": "server01"},"fields": { "value": 100}}]} ` )
2015-02-10 22:57:46 +00:00
if status != http . StatusOK {
t . Fatalf ( "unexpected status: %d" , status )
}
2015-02-15 20:22:58 +00:00
time . Sleep ( 100 * time . Millisecond ) // Ensure data node picks up write.
2015-02-10 22:57:46 +00:00
2015-02-19 21:22:04 +00:00
srvr . Restart ( ) // Ensure data is queryable across restarts.
2015-02-10 22:57:46 +00:00
query := map [ string ] string { "db" : "foo" , "q" : "select value from cpu" }
status , body := MustHTTP ( "GET" , s . URL + ` /query ` , query , nil , "" )
if status != http . StatusOK {
t . Logf ( "query %s\n" , query )
t . Log ( body )
t . Errorf ( "unexpected status: %d" , status )
}
r := & influxdb . Results { }
if err := json . Unmarshal ( [ ] byte ( body ) , r ) ; err != nil {
t . Logf ( "query : %s\n" , query )
t . Log ( body )
t . Error ( err )
}
if len ( r . Results ) != 1 {
t . Fatalf ( "unexpected results count" )
}
result := r . Results [ 0 ]
2015-02-23 05:21:49 +00:00
if len ( result . Series ) != 1 {
t . Fatalf ( "unexpected row count, expected: %d, actual: %d" , 1 , len ( result . Series ) )
2015-02-10 22:57:46 +00:00
}
2015-02-23 05:21:49 +00:00
row := result . Series [ 0 ]
2015-02-10 22:57:46 +00:00
timestamp , _ := time . Parse ( time . RFC3339Nano , row . Values [ 0 ] [ 0 ] . ( string ) )
if timestamp . IsZero ( ) {
t . Fatalf ( "failed to write a default time, actual: %v" , row . Values [ 0 ] [ 0 ] )
}
if ! timestamp . After ( now ) {
2015-02-15 21:16:07 +00:00
t . Fatalf ( "time was not valid. expected something after %v, actual: %v" , now , timestamp )
}
}
2015-02-17 20:33:50 +00:00
func TestHandler_serveWriteSeriesStringValues ( t * testing . T ) {
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
srvr . CreateDatabase ( "foo" )
srvr . CreateRetentionPolicy ( "foo" , influxdb . NewRetentionPolicy ( "bar" ) )
srvr . SetDefaultRetentionPolicy ( "foo" , "bar" )
s := NewHTTPServer ( srvr )
defer s . Close ( )
2015-02-23 22:37:10 +00:00
status , _ := MustHTTP ( "POST" , s . URL + ` /write ` , nil , nil , ` { "database" : "foo", "retentionPolicy" : "bar", "points": [ { "name": "logs", "tags": { "host": "server01"},"fields": { "event": "disk full"}}]} ` )
2015-02-17 20:33:50 +00:00
if status != http . StatusOK {
t . Fatalf ( "unexpected status: %d" , status )
}
time . Sleep ( 100 * time . Millisecond ) // Ensure data node picks up write.
2015-02-19 21:22:04 +00:00
srvr . Restart ( ) // Ensure data is queryable across restarts.
2015-02-17 20:33:50 +00:00
query := map [ string ] string { "db" : "foo" , "q" : "select event from logs" }
status , body := MustHTTP ( "GET" , s . URL + ` /query ` , query , nil , "" )
if status != http . StatusOK {
t . Logf ( "query %s\n" , query )
t . Log ( body )
t . Errorf ( "unexpected status: %d" , status )
}
r := & influxdb . Results { }
if err := json . Unmarshal ( [ ] byte ( body ) , r ) ; err != nil {
t . Logf ( "query : %s\n" , query )
t . Log ( body )
t . Error ( err )
}
if len ( r . Results ) != 1 {
t . Fatalf ( "unexpected results count" )
}
result := r . Results [ 0 ]
2015-02-23 05:21:49 +00:00
if len ( result . Series ) != 1 {
t . Fatalf ( "unexpected row count, expected: %d, actual: %d" , 1 , len ( result . Series ) )
2015-02-17 20:33:50 +00:00
}
2015-02-23 05:21:49 +00:00
if result . Series [ 0 ] . Values [ 0 ] [ 1 ] != "disk full" {
t . Fatalf ( "unexpected string value, actual: %s" , result . Series [ 0 ] . Values [ 0 ] [ 1 ] )
2015-02-17 20:33:50 +00:00
}
}
2015-02-17 20:37:24 +00:00
func TestHandler_serveWriteSeriesBoolValues ( t * testing . T ) {
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
srvr . CreateDatabase ( "foo" )
srvr . CreateRetentionPolicy ( "foo" , influxdb . NewRetentionPolicy ( "bar" ) )
srvr . SetDefaultRetentionPolicy ( "foo" , "bar" )
s := NewHTTPServer ( srvr )
defer s . Close ( )
2015-02-23 22:37:10 +00:00
status , _ := MustHTTP ( "POST" , s . URL + ` /write ` , nil , nil , ` { "database" : "foo", "retentionPolicy" : "bar", "points": [ { "name": "disk", "tags": { "host": "server01"},"fields": { "full": false}}]} ` )
2015-02-17 20:37:24 +00:00
if status != http . StatusOK {
t . Fatalf ( "unexpected status: %d" , status )
}
time . Sleep ( 100 * time . Millisecond ) // Ensure data node picks up write.
2015-02-19 21:22:04 +00:00
srvr . Restart ( ) // Ensure data is queryable across restarts.
2015-02-17 20:37:24 +00:00
query := map [ string ] string { "db" : "foo" , "q" : "select full from disk" }
status , body := MustHTTP ( "GET" , s . URL + ` /query ` , query , nil , "" )
if status != http . StatusOK {
t . Logf ( "query %s\n" , query )
t . Log ( body )
t . Errorf ( "unexpected status: %d" , status )
}
r := & influxdb . Results { }
if err := json . Unmarshal ( [ ] byte ( body ) , r ) ; err != nil {
t . Logf ( "query : %s\n" , query )
t . Log ( body )
t . Error ( err )
}
if len ( r . Results ) != 1 {
t . Fatalf ( "unexpected results count" )
}
result := r . Results [ 0 ]
2015-02-23 05:21:49 +00:00
if len ( result . Series ) != 1 {
t . Fatalf ( "unexpected row count, expected: %d, actual: %d" , 1 , len ( result . Series ) )
2015-02-17 20:37:24 +00:00
}
2015-02-23 05:21:49 +00:00
if result . Series [ 0 ] . Values [ 0 ] [ 1 ] != false {
t . Fatalf ( "unexpected string value, actual: %s" , result . Series [ 0 ] . Values [ 0 ] [ 1 ] )
2015-02-17 20:37:24 +00:00
}
}
2015-02-19 21:36:22 +00:00
func TestHandler_serveWriteSeriesBatch ( t * testing . T ) {
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
srvr . CreateDatabase ( "foo" )
srvr . CreateRetentionPolicy ( "foo" , influxdb . NewRetentionPolicy ( "bar" ) )
srvr . SetDefaultRetentionPolicy ( "foo" , "bar" )
s := NewHTTPServer ( srvr )
defer s . Close ( )
batch := `
{
"database" : "foo" ,
"retentionPolicy" : "bar" ,
"points" : [
{
"name" : "disk" ,
"timestamp" : "2009-11-10T23:00:00Z" ,
"tags" : {
"host" : "server01"
} ,
2015-02-23 22:37:10 +00:00
"fields" : {
2015-02-19 21:36:22 +00:00
"full" : false
}
} ,
{
"name" : "disk" ,
"timestamp" : "2009-11-10T23:00:01Z" ,
"tags" : {
"host" : "server01"
} ,
2015-02-23 22:37:10 +00:00
"fields" : {
2015-02-19 21:36:22 +00:00
"full" : true
}
} ,
{
"name" : "disk" ,
"timestamp" : "2009-11-10T23:00:02Z" ,
"tags" : {
"host" : "server02"
} ,
2015-02-23 22:37:10 +00:00
"fields" : {
2015-02-19 21:36:22 +00:00
"full_pct" : 64
}
}
]
}
`
status , body := MustHTTP ( "POST" , s . URL + ` /write ` , nil , nil , batch )
if status != http . StatusOK {
t . Log ( body )
t . Fatalf ( "unexpected status: %d" , status )
}
time . Sleep ( 200 * time . Millisecond ) // Ensure data node picks up write.
query := map [ string ] string { "db" : "foo" , "q" : "select * from disk" }
status , body = MustHTTP ( "GET" , s . URL + ` /query ` , query , nil , "" )
if status != http . StatusOK {
t . Logf ( "query %s\n" , query )
t . Log ( body )
t . Errorf ( "unexpected status: %d" , status )
}
r := & influxdb . Results { }
if err := json . Unmarshal ( [ ] byte ( body ) , r ) ; err != nil {
t . Logf ( "query : %s\n" , query )
t . Log ( body )
t . Error ( err )
}
if len ( r . Results ) != 1 {
t . Fatalf ( "unexpected results count" )
}
result := r . Results [ 0 ]
2015-02-23 05:21:49 +00:00
if len ( result . Series ) != 1 {
t . Fatalf ( "unexpected row count, expected: %d, actual: %d" , 1 , len ( result . Series ) )
2015-02-19 21:36:22 +00:00
}
2015-02-23 05:21:49 +00:00
if len ( result . Series [ 0 ] . Columns ) != 3 {
t . Fatalf ( "unexpected column count, expected: %d, actual: %d" , 3 , len ( result . Series [ 0 ] . Columns ) )
2015-02-20 07:32:59 +00:00
}
2015-02-23 05:21:49 +00:00
if len ( result . Series [ 0 ] . Values ) != 3 {
t . Fatalf ( "unexpected values count, expected: %d, actual: %d" , 3 , len ( result . Series [ 0 ] . Values ) )
2015-02-19 21:36:22 +00:00
}
}
2015-02-17 20:04:10 +00:00
func TestHandler_serveWriteSeriesInvalidQueryField ( t * testing . T ) {
2015-02-15 21:16:07 +00:00
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
srvr . CreateDatabase ( "foo" )
srvr . CreateRetentionPolicy ( "foo" , influxdb . NewRetentionPolicy ( "bar" ) )
srvr . SetDefaultRetentionPolicy ( "foo" , "bar" )
s := NewHTTPServer ( srvr )
defer s . Close ( )
2015-02-23 22:37:10 +00:00
status , _ := MustHTTP ( "POST" , s . URL + ` /write ` , nil , nil , ` { "database" : "foo", "retentionPolicy" : "bar", "points": [ { "name": "cpu", "tags": { "host": "server01"},"fields": { "value": 100}}]} ` )
2015-02-15 21:16:07 +00:00
if status != http . StatusOK {
t . Fatalf ( "unexpected status: %d" , status )
}
time . Sleep ( 100 * time . Millisecond ) // Ensure data node picks up write.
query := map [ string ] string { "db" : "foo" , "q" : "select bar from cpu" }
status , body := MustHTTP ( "GET" , s . URL + ` /query ` , query , nil , "" )
if status != http . StatusInternalServerError {
t . Logf ( "query %s\n" , query )
t . Log ( body )
t . Errorf ( "unexpected status: %d" , status )
}
r := & influxdb . Results { }
if err := json . Unmarshal ( [ ] byte ( body ) , r ) ; err != nil {
t . Logf ( "query : %s\n" , query )
t . Log ( body )
t . Error ( err )
}
if len ( r . Results ) != 1 {
t . Fatalf ( "unexpected results count" )
}
result := r . Results [ 0 ]
2015-02-23 05:21:49 +00:00
if len ( result . Series ) != 0 {
t . Fatalf ( "unexpected row count, expected: %d, actual: %d" , 0 , len ( result . Series ) )
2015-02-15 21:16:07 +00:00
}
if result . Err . Error ( ) != "field not found: bar" {
t . Fatalf ( "unexpected error returned, actual: %s" , result . Err . Error ( ) )
2015-02-10 22:57:46 +00:00
}
}
2015-02-15 23:48:19 +00:00
func TestHandler_serveWriteSeriesFieldTypeConflict ( t * testing . T ) {
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
srvr . CreateDatabase ( "foo" )
srvr . CreateRetentionPolicy ( "foo" , influxdb . NewRetentionPolicy ( "bar" ) )
srvr . SetDefaultRetentionPolicy ( "foo" , "bar" )
s := NewHTTPServer ( srvr )
defer s . Close ( )
2015-02-23 22:37:10 +00:00
status , _ := MustHTTP ( "POST" , s . URL + ` /write ` , nil , nil , ` { "database" : "foo", "retentionPolicy" : "bar", "points": [ { "name": "cpu", "tags": { "host": "server01"},"fields": { "value": 100}}]} ` )
2015-02-15 23:48:19 +00:00
if status != http . StatusOK {
t . Fatalf ( "unexpected status: %d" , status )
}
2015-02-23 22:37:10 +00:00
status , body := MustHTTP ( "POST" , s . URL + ` /write ` , nil , nil , ` { "database" : "foo", "retentionPolicy" : "bar", "points": [ { "name": "cpu", "tags": { "host": "server01"},"fields": { "value": "foo"}}]} ` )
2015-02-15 23:48:19 +00:00
if status != http . StatusInternalServerError {
t . Errorf ( "unexpected status: %d" , status )
}
r := & influxdb . Results { }
if err := json . Unmarshal ( [ ] byte ( body ) , r ) ; err != nil {
t . Log ( body )
t . Error ( err )
}
if len ( r . Results ) != 0 {
t . Fatalf ( "unexpected results count" )
}
if r . Err . Error ( ) != "field \"value\" is type string, mapped as type number" {
t . Fatalf ( "unexpected error returned, actual: %s" , r . Err . Error ( ) )
}
}
2015-01-28 04:36:19 +00:00
func TestHandler_serveShowSeries ( t * testing . T ) {
2015-02-05 22:54:32 +00:00
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
2015-01-28 04:36:19 +00:00
srvr . CreateDatabase ( "foo" )
srvr . CreateRetentionPolicy ( "foo" , influxdb . NewRetentionPolicy ( "bar" ) )
2015-01-28 16:50:14 +00:00
srvr . SetDefaultRetentionPolicy ( "foo" , "bar" )
2015-01-28 04:36:19 +00:00
s := NewHTTPServer ( srvr )
defer s . Close ( )
status , body := MustHTTP ( "POST" , s . URL + ` /write ` , nil , nil , ` { "database" : "foo" , "retentionPolicy" : "bar" , "points" : [
2015-02-23 22:37:10 +00:00
{ "name" : "cpu" , "tags" : { "host" : "server01" } , "timestamp" : "2009-11-10T23:00:00Z" , "fields" : { "value" : 100 } } ,
{ "name" : "cpu" , "tags" : { "host" : "server01" , "region" : "uswest" } , "timestamp" : "2009-11-10T23:00:00Z" , "fields" : { "value" : 100 } } ,
{ "name" : "cpu" , "tags" : { "host" : "server01" , "region" : "useast" } , "timestamp" : "2009-11-10T23:00:00Z" , "fields" : { "value" : 100 } } ,
{ "name" : "cpu" , "tags" : { "host" : "server02" , "region" : "useast" } , "timestamp" : "2009-11-10T23:00:00Z" , "fields" : { "value" : 100 } } ,
{ "name" : "gpu" , "tags" : { "host" : "server02" , "region" : "useast" } , "timestamp" : "2009-11-10T23:00:00Z" , "fields" : { "value" : 100 } } ,
{ "name" : "gpu" , "tags" : { "host" : "server03" , "region" : "caeast" } , "timestamp" : "2009-11-10T23:00:00Z" , "fields" : { "value" : 100 } }
2015-01-28 04:36:19 +00:00
] } ` )
if status != http . StatusOK {
t . Log ( body )
t . Fatalf ( "unexpected status after write: %d" , status )
}
2015-01-28 08:45:21 +00:00
var tests = [ ] struct {
q string
2015-01-28 16:50:14 +00:00
r * influxdb . Results
2015-01-28 08:45:21 +00:00
err string
} {
// SHOW SERIES
{
q : ` SHOW SERIES ` ,
2015-01-28 16:50:14 +00:00
r : & influxdb . Results {
Results : [ ] * influxdb . Result {
2015-02-01 20:33:12 +00:00
{
2015-02-23 05:21:49 +00:00
Series : [ ] * influxql . Row {
2015-02-01 20:33:12 +00:00
{
2015-01-28 16:50:14 +00:00
Name : "cpu" ,
Columns : [ ] string { "host" , "region" } ,
Values : [ ] [ ] interface { } {
str2iface ( [ ] string { "server01" , "" } ) ,
str2iface ( [ ] string { "server01" , "uswest" } ) ,
str2iface ( [ ] string { "server01" , "useast" } ) ,
str2iface ( [ ] string { "server02" , "useast" } ) ,
} ,
} ,
2015-02-01 20:33:12 +00:00
{
2015-01-28 16:50:14 +00:00
Name : "gpu" ,
Columns : [ ] string { "host" , "region" } ,
Values : [ ] [ ] interface { } {
str2iface ( [ ] string { "server02" , "useast" } ) ,
2015-02-16 20:30:58 +00:00
str2iface ( [ ] string { "server03" , "caeast" } ) ,
2015-01-28 16:50:14 +00:00
} ,
} ,
} ,
} ,
} ,
} ,
2015-01-28 15:37:25 +00:00
} ,
2015-01-28 16:50:14 +00:00
// SHOW SERIES ... LIMIT
// {
// q: `SHOW SERIES LIMIT 1`,
// r: &influxdb.Results{
// Results: []*influxdb.Result{
// &influxdb.Result{
2015-02-23 05:21:49 +00:00
// Series: []*influxql.Row{
2015-01-28 16:50:14 +00:00
// &influxql.Row{
// Name: "cpu",
// Columns: []string{"host", "region"},
// Values: [][]interface{}{
// str2iface([]string{"server01", ""}),
// str2iface([]string{"server01", "uswest"}),
// str2iface([]string{"server01", "useast"}),
// str2iface([]string{"server02", "useast"}),
// },
// },
// },
// },
// },
// },
// },
// SHOW SERIES FROM
2015-01-28 15:37:25 +00:00
{
2015-01-28 16:50:14 +00:00
q : ` SHOW SERIES FROM cpu ` ,
r : & influxdb . Results {
Results : [ ] * influxdb . Result {
2015-02-01 20:33:12 +00:00
{
2015-02-23 05:21:49 +00:00
Series : [ ] * influxql . Row {
2015-02-01 20:33:12 +00:00
{
2015-01-28 16:50:14 +00:00
Name : "cpu" ,
Columns : [ ] string { "host" , "region" } ,
Values : [ ] [ ] interface { } {
str2iface ( [ ] string { "server01" , "" } ) ,
str2iface ( [ ] string { "server01" , "uswest" } ) ,
str2iface ( [ ] string { "server01" , "useast" } ) ,
str2iface ( [ ] string { "server02" , "useast" } ) ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
// SHOW SERIES WHERE
{
q : ` SHOW SERIES WHERE region = 'uswest' ` ,
r : & influxdb . Results {
Results : [ ] * influxdb . Result {
2015-02-01 20:33:12 +00:00
{
2015-02-23 05:21:49 +00:00
Series : [ ] * influxql . Row {
2015-02-01 20:33:12 +00:00
{
2015-01-28 16:50:14 +00:00
Name : "cpu" ,
Columns : [ ] string { "host" , "region" } ,
Values : [ ] [ ] interface { } {
str2iface ( [ ] string { "server01" , "uswest" } ) ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
2015-02-16 20:30:58 +00:00
// SHOW SERIES WHERE =~ regex
{
q : ` SHOW SERIES WHERE region =~ 'ca.*' ` ,
r : & influxdb . Results {
Results : [ ] * influxdb . Result {
{
2015-02-23 05:21:49 +00:00
Series : [ ] * influxql . Row {
2015-02-16 20:30:58 +00:00
{
Name : "gpu" ,
Columns : [ ] string { "host" , "region" } ,
Values : [ ] [ ] interface { } {
str2iface ( [ ] string { "server03" , "caeast" } ) ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
// SHOW SERIES WHERE !~ regex
{
q : ` SHOW SERIES WHERE host !~ 'server0[12]' ` ,
r : & influxdb . Results {
Results : [ ] * influxdb . Result {
{
2015-02-23 05:21:49 +00:00
Series : [ ] * influxql . Row {
2015-02-16 20:30:58 +00:00
{
Name : "gpu" ,
Columns : [ ] string { "host" , "region" } ,
Values : [ ] [ ] interface { } {
str2iface ( [ ] string { "server03" , "caeast" } ) ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
2015-01-28 16:50:14 +00:00
// SHOW SERIES FROM ... WHERE
{
q : ` SHOW SERIES FROM cpu WHERE region = 'useast' ` ,
r : & influxdb . Results {
Results : [ ] * influxdb . Result {
2015-02-01 20:33:12 +00:00
{
2015-02-23 05:21:49 +00:00
Series : [ ] * influxql . Row {
2015-02-01 20:33:12 +00:00
{
2015-01-28 16:50:14 +00:00
Name : "cpu" ,
Columns : [ ] string { "host" , "region" } ,
Values : [ ] [ ] interface { } {
str2iface ( [ ] string { "server01" , "useast" } ) ,
str2iface ( [ ] string { "server02" , "useast" } ) ,
} ,
} ,
} ,
} ,
} ,
} ,
2015-01-28 08:45:21 +00:00
} ,
}
for i , tt := range tests {
query := map [ string ] string { "db" : "foo" , "q" : tt . q }
status , body = MustHTTP ( "GET" , s . URL + ` /query ` , query , nil , "" )
if status != http . StatusOK {
t . Logf ( "query #%d: %s" , i , tt . q )
t . Log ( body )
t . Errorf ( "unexpected status: %d" , status )
}
2015-01-28 04:36:19 +00:00
2015-01-28 08:45:21 +00:00
r := & influxdb . Results { }
if err := json . Unmarshal ( [ ] byte ( body ) , r ) ; err != nil {
t . Logf ( "query #%d: %s" , i , tt . q )
t . Log ( body )
2015-01-28 16:50:14 +00:00
t . Error ( err )
2015-01-28 08:45:21 +00:00
}
2015-01-28 16:50:14 +00:00
if ! reflect . DeepEqual ( tt . err , errstring ( r . Err ) ) {
2015-02-16 20:30:58 +00:00
t . Logf ( "query #%d: %s" , i , tt . q )
2015-01-28 16:50:14 +00:00
t . Errorf ( "%d. %s: error mismatch:\n exp=%s\n got=%s\n\n" , i , tt . q , tt . err , r . Err )
} else if tt . err == "" && ! reflect . DeepEqual ( tt . r , r ) {
2015-02-16 20:30:58 +00:00
t . Logf ( "query #%d: %s" , i , tt . q )
t . Logf ( "exp = %s" , mustMarshalJSON ( tt . r ) )
t . Logf ( "got = %s" , body )
2015-01-28 16:50:14 +00:00
t . Errorf ( "%d. %s: result mismatch:\n\nexp=%#v\n\ngot=%#v\n\n" , i , tt . q , tt . r , r )
2015-01-28 08:45:21 +00:00
}
2015-01-28 04:36:19 +00:00
}
2015-01-28 08:45:21 +00:00
}
2015-01-28 04:36:19 +00:00
2015-01-28 08:45:21 +00:00
// str2iface converts an array of strings to an array of interfaces.
func str2iface ( strs [ ] string ) [ ] interface { } {
2015-01-28 16:50:14 +00:00
a := make ( [ ] interface { } , 0 , len ( strs ) )
2015-01-28 08:45:21 +00:00
for _ , s := range strs {
a = append ( a , interface { } ( s ) )
}
return a
2015-01-28 04:36:19 +00:00
}
2015-01-28 05:51:09 +00:00
func TestHandler_serveShowMeasurements ( t * testing . T ) {
2015-02-05 22:54:32 +00:00
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
2015-01-28 05:51:09 +00:00
srvr . CreateDatabase ( "foo" )
srvr . CreateRetentionPolicy ( "foo" , influxdb . NewRetentionPolicy ( "bar" ) )
s := NewHTTPServer ( srvr )
defer s . Close ( )
status , body := MustHTTP ( "POST" , s . URL + ` /write ` , nil , nil , ` { "database" : "foo" , "retentionPolicy" : "bar" , "points" : [
2015-02-23 22:37:10 +00:00
{ "name" : "cpu" , "tags" : { "host" : "server01" } , "timestamp" : "2009-11-10T23:00:00Z" , "fields" : { "value" : 100 } } ,
{ "name" : "cpu" , "tags" : { "host" : "server01" , "region" : "uswest" } , "timestamp" : "2009-11-10T23:00:00Z" , "fields" : { "value" : 100 } } ,
{ "name" : "cpu" , "tags" : { "host" : "server01" , "region" : "useast" } , "timestamp" : "2009-11-10T23:00:00Z" , "fields" : { "value" : 100 } } ,
{ "name" : "cpu" , "tags" : { "host" : "server02" , "region" : "useast" } , "timestamp" : "2009-11-10T23:00:00Z" , "fields" : { "value" : 100 } } ,
{ "name" : "gpu" , "tags" : { "host" : "server02" , "region" : "useast" } , "timestamp" : "2009-11-10T23:00:00Z" , "fields" : { "value" : 100 } } ,
{ "name" : "gpu" , "tags" : { "host" : "server02" , "region" : "caeast" } , "timestamp" : "2009-11-10T23:00:00Z" , "fields" : { "value" : 100 } } ,
{ "name" : "other" , "tags" : { "host" : "server03" , "region" : "caeast" } , "timestamp" : "2009-11-10T23:00:00Z" , "fields" : { "value" : 100 } }
2015-01-28 05:51:09 +00:00
] } ` )
if status != http . StatusOK {
t . Log ( body )
t . Fatalf ( "unexpected status after write: %d" , status )
}
2015-01-28 15:37:25 +00:00
var tests = [ ] struct {
q string
r string
err string
} {
2015-02-12 04:03:44 +00:00
// SHOW MEASUREMENTS
2015-01-28 15:37:25 +00:00
{
q : ` SHOW MEASUREMENTS LIMIT 2 ` ,
2015-02-23 05:21:49 +00:00
r : ` { "results":[ { "series":[ { "name":"measurements","columns":["name"],"values":[["cpu"],["gpu"]]}]}]} ` ,
2015-01-28 15:37:25 +00:00
} ,
2015-02-16 20:30:58 +00:00
// SHOW MEASUREMENTS WHERE =~ regex
{
q : ` SHOW MEASUREMENTS WHERE region =~ 'ca.*' ` ,
2015-02-23 05:21:49 +00:00
r : ` { "results":[ { "series":[ { "name":"measurements","columns":["name"],"values":[["gpu"],["other"]]}]}]} ` ,
2015-02-16 20:30:58 +00:00
} ,
// SHOW MEASUREMENTS WHERE !~ regex
{
q : ` SHOW MEASUREMENTS WHERE region !~ 'ca.*' ` ,
2015-02-23 05:21:49 +00:00
r : ` { "results":[ { "series":[ { "name":"measurements","columns":["name"],"values":[["cpu"]]}]}]} ` ,
2015-02-16 20:30:58 +00:00
} ,
2015-01-28 05:51:09 +00:00
}
2015-01-28 15:37:25 +00:00
for i , tt := range tests {
query := map [ string ] string { "db" : "foo" , "q" : tt . q }
status , body = MustHTTP ( "GET" , s . URL + ` /query ` , query , nil , "" )
if status != http . StatusOK {
t . Logf ( "query #%d: %s" , i , tt . q )
t . Log ( body )
t . Errorf ( "unexpected status: %d" , status )
}
r := & influxdb . Results { }
if err := json . Unmarshal ( [ ] byte ( body ) , r ) ; err != nil {
t . Logf ( "query #%d: %s" , i , tt . q )
t . Log ( body )
t . Error ( "error marshaling result: " , err )
}
if body != tt . r {
t . Errorf ( "result mismatch\n exp: %s\n got: %s\n" , tt . r , body )
}
}
2015-01-28 05:51:09 +00:00
}
2015-01-29 01:26:15 +00:00
func TestHandler_serveShowTagKeys ( t * testing . T ) {
2015-02-05 22:54:32 +00:00
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
2015-01-29 01:26:15 +00:00
srvr . CreateDatabase ( "foo" )
srvr . CreateRetentionPolicy ( "foo" , influxdb . NewRetentionPolicy ( "bar" ) )
srvr . SetDefaultRetentionPolicy ( "foo" , "bar" )
s := NewHTTPServer ( srvr )
defer s . Close ( )
status , body := MustHTTP ( "POST" , s . URL + ` /write ` , nil , nil , ` { "database" : "foo" , "retentionPolicy" : "bar" , "points" : [
2015-02-23 22:37:10 +00:00
{ "name" : "cpu" , "tags" : { "host" : "server01" } , "timestamp" : "2009-11-10T23:00:00Z" , "fields" : { "value" : 100 } } ,
{ "name" : "cpu" , "tags" : { "host" : "server01" , "region" : "uswest" } , "timestamp" : "2009-11-10T23:00:00Z" , "fields" : { "value" : 100 } } ,
{ "name" : "cpu" , "tags" : { "host" : "server01" , "region" : "useast" } , "timestamp" : "2009-11-10T23:00:00Z" , "fields" : { "value" : 100 } } ,
{ "name" : "cpu" , "tags" : { "host" : "server02" , "region" : "useast" } , "timestamp" : "2009-11-10T23:00:00Z" , "fields" : { "value" : 100 } } ,
{ "name" : "gpu" , "tags" : { "host" : "server02" , "region" : "useast" } , "timestamp" : "2009-11-10T23:00:00Z" , "fields" : { "value" : 100 } } ,
{ "name" : "gpu" , "tags" : { "host" : "server03" , "region" : "caeast" } , "timestamp" : "2009-11-10T23:00:00Z" , "fields" : { "value" : 100 } }
2015-01-29 01:26:15 +00:00
] } ` )
if status != http . StatusOK {
t . Log ( body )
t . Fatalf ( "unexpected status after write: %d" , status )
}
var tests = [ ] struct {
q string
r * influxdb . Results
err string
} {
// SHOW TAG KEYS
{
q : ` SHOW TAG KEYS ` ,
r : & influxdb . Results {
Results : [ ] * influxdb . Result {
2015-02-01 20:33:12 +00:00
{
2015-02-23 05:21:49 +00:00
Series : [ ] * influxql . Row {
2015-02-01 20:33:12 +00:00
{
2015-01-29 01:26:15 +00:00
Name : "cpu" ,
2015-01-29 02:31:23 +00:00
Columns : [ ] string { "tagKey" } ,
Values : [ ] [ ] interface { } {
str2iface ( [ ] string { "host" } ) ,
str2iface ( [ ] string { "region" } ) ,
} ,
2015-01-29 01:26:15 +00:00
} ,
2015-02-01 20:33:12 +00:00
{
2015-01-29 01:26:15 +00:00
Name : "gpu" ,
2015-01-29 02:31:23 +00:00
Columns : [ ] string { "tagKey" } ,
Values : [ ] [ ] interface { } {
str2iface ( [ ] string { "host" } ) ,
str2iface ( [ ] string { "region" } ) ,
} ,
2015-01-29 01:26:15 +00:00
} ,
} ,
} ,
} ,
} ,
} ,
// SHOW TAG KEYS FROM...
{
q : ` SHOW TAG KEYS FROM cpu ` ,
r : & influxdb . Results {
Results : [ ] * influxdb . Result {
2015-02-01 20:33:12 +00:00
{
2015-02-23 05:21:49 +00:00
Series : [ ] * influxql . Row {
2015-02-01 20:33:12 +00:00
{
2015-01-29 01:26:15 +00:00
Name : "cpu" ,
2015-01-29 02:31:23 +00:00
Columns : [ ] string { "tagKey" } ,
Values : [ ] [ ] interface { } {
str2iface ( [ ] string { "host" } ) ,
str2iface ( [ ] string { "region" } ) ,
} ,
2015-01-29 01:26:15 +00:00
} ,
} ,
} ,
} ,
} ,
} ,
2015-02-06 20:41:12 +00:00
// SHOW TAG KEYS FROM <non-existant measurement>
{
q : ` SHOW TAG KEYS FROM bad ` ,
err : ` measurement "bad" not found ` ,
} ,
2015-01-29 01:26:15 +00:00
}
for i , tt := range tests {
query := map [ string ] string { "db" : "foo" , "q" : tt . q }
status , body = MustHTTP ( "GET" , s . URL + ` /query ` , query , nil , "" )
2015-02-06 20:41:12 +00:00
if ( tt . err == "" && status != http . StatusOK ) ||
( tt . err != "" && status != http . StatusInternalServerError ) {
2015-01-29 01:26:15 +00:00
t . Logf ( "query #%d: %s" , i , tt . q )
2015-02-06 20:41:12 +00:00
t . Logf ( "body = %s\n" , body )
2015-01-29 01:26:15 +00:00
t . Errorf ( "unexpected status: %d" , status )
}
r := & influxdb . Results { }
if err := json . Unmarshal ( [ ] byte ( body ) , r ) ; err != nil {
t . Logf ( "query #%d: %s" , i , tt . q )
2015-02-06 20:41:12 +00:00
t . Logf ( "body = %s\n" , body )
2015-01-29 01:26:15 +00:00
t . Error ( err )
}
2015-02-06 20:41:12 +00:00
if ! reflect . DeepEqual ( tt . err , errstring ( r . Results [ 0 ] . Err ) ) {
t . Logf ( "body = %s\n" , body )
fmt . Printf ( "r.Results[0].Err) = %v\n" , r . Results [ 0 ] . Err )
t . Errorf ( "%d. %s: error mismatch:\n exp=%s\n got=%s\n\n" , i , tt . q , tt . err , errstring ( r . Results [ 0 ] . Err ) )
2015-01-29 20:00:15 +00:00
} else if tt . err == "" && ! reflect . DeepEqual ( tt . r , r ) {
b , _ := json . Marshal ( tt . r )
t . Log ( string ( b ) )
t . Log ( body )
t . Errorf ( "%d. %s: result mismatch:\n\nexp=%#v\n\ngot=%#v\n\n" , i , tt . q , tt . r , r )
}
}
}
func TestHandler_serveShowTagValues ( t * testing . T ) {
2015-02-05 22:54:32 +00:00
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
2015-01-29 20:00:15 +00:00
srvr . CreateDatabase ( "foo" )
srvr . CreateRetentionPolicy ( "foo" , influxdb . NewRetentionPolicy ( "bar" ) )
srvr . SetDefaultRetentionPolicy ( "foo" , "bar" )
s := NewHTTPServer ( srvr )
defer s . Close ( )
status , body := MustHTTP ( "POST" , s . URL + ` /write ` , nil , nil , ` { "database" : "foo" , "retentionPolicy" : "bar" , "points" : [
2015-02-23 22:37:10 +00:00
{ "name" : "cpu" , "tags" : { "host" : "server01" } , "timestamp" : "2009-11-10T23:00:00Z" , "fields" : { "value" : 100 } } ,
{ "name" : "cpu" , "tags" : { "host" : "server01" , "region" : "uswest" } , "timestamp" : "2009-11-10T23:00:00Z" , "fields" : { "value" : 100 } } ,
{ "name" : "cpu" , "tags" : { "host" : "server01" , "region" : "useast" } , "timestamp" : "2009-11-10T23:00:00Z" , "fields" : { "value" : 100 } } ,
{ "name" : "cpu" , "tags" : { "host" : "server02" , "region" : "useast" } , "timestamp" : "2009-11-10T23:00:00Z" , "fields" : { "value" : 100 } } ,
{ "name" : "gpu" , "tags" : { "host" : "server02" , "region" : "useast" } , "timestamp" : "2009-11-10T23:00:00Z" , "fields" : { "value" : 100 } } ,
{ "name" : "gpu" , "tags" : { "host" : "server03" , "region" : "caeast" } , "timestamp" : "2009-11-10T23:00:00Z" , "fields" : { "value" : 100 } }
2015-01-29 20:00:15 +00:00
] } ` )
if status != http . StatusOK {
t . Log ( body )
t . Fatalf ( "unexpected status after write: %d" , status )
}
var tests = [ ] struct {
q string
r * influxdb . Results
err string
} {
// SHOW TAG VALUES
{
q : ` SHOW TAG VALUES WITH KEY = host ` ,
r : & influxdb . Results {
Results : [ ] * influxdb . Result {
2015-02-01 20:33:12 +00:00
{
2015-02-23 05:21:49 +00:00
Series : [ ] * influxql . Row {
2015-02-01 20:33:12 +00:00
{
2015-02-23 06:25:27 +00:00
Name : "hostTagValues" ,
Columns : [ ] string { "host" } ,
2015-01-29 20:00:15 +00:00
Values : [ ] [ ] interface { } {
str2iface ( [ ] string { "server01" } ) ,
str2iface ( [ ] string { "server02" } ) ,
2015-02-16 20:30:58 +00:00
str2iface ( [ ] string { "server03" } ) ,
2015-01-29 20:00:15 +00:00
} ,
} ,
} ,
} ,
} ,
} ,
} ,
// SHOW TAG VALUES FROM ...
{
q : ` SHOW TAG VALUES FROM cpu WITH KEY = host ` ,
r : & influxdb . Results {
Results : [ ] * influxdb . Result {
2015-02-01 20:33:12 +00:00
{
2015-02-23 05:21:49 +00:00
Series : [ ] * influxql . Row {
2015-02-01 20:33:12 +00:00
{
2015-02-23 06:25:27 +00:00
Name : "hostTagValues" ,
Columns : [ ] string { "host" } ,
2015-01-29 20:00:15 +00:00
Values : [ ] [ ] interface { } {
str2iface ( [ ] string { "server01" } ) ,
str2iface ( [ ] string { "server02" } ) ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
// SHOW TAG VALUES FROM ... WHERE ...
{
q : ` SHOW TAG VALUES FROM cpu WITH KEY = host WHERE region = 'uswest' ` ,
r : & influxdb . Results {
Results : [ ] * influxdb . Result {
2015-02-01 20:33:12 +00:00
{
2015-02-23 05:21:49 +00:00
Series : [ ] * influxql . Row {
2015-02-01 20:33:12 +00:00
{
2015-02-23 06:25:27 +00:00
Name : "hostTagValues" ,
Columns : [ ] string { "host" } ,
2015-01-29 20:00:15 +00:00
Values : [ ] [ ] interface { } {
str2iface ( [ ] string { "server01" } ) ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
2015-02-16 20:30:58 +00:00
// SHOW TAG VALUES FROM ... WHERE =~ regex
{
q : ` SHOW TAG VALUES WITH KEY = host WHERE region =~ 'ca.*' ` ,
r : & influxdb . Results {
Results : [ ] * influxdb . Result {
{
2015-02-23 05:21:49 +00:00
Series : [ ] * influxql . Row {
2015-02-16 20:30:58 +00:00
{
2015-02-23 06:25:27 +00:00
Name : "hostTagValues" ,
Columns : [ ] string { "host" } ,
2015-02-16 20:30:58 +00:00
Values : [ ] [ ] interface { } {
str2iface ( [ ] string { "server03" } ) ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
// SHOW TAG VALUES FROM ... WHERE !~ regex
{
q : ` SHOW TAG VALUES WITH KEY = region WHERE host !~ 'server0[12]' ` ,
r : & influxdb . Results {
Results : [ ] * influxdb . Result {
{
2015-02-23 05:21:49 +00:00
Series : [ ] * influxql . Row {
2015-02-16 20:30:58 +00:00
{
2015-02-23 06:25:27 +00:00
Name : "regionTagValues" ,
Columns : [ ] string { "region" } ,
2015-02-16 20:30:58 +00:00
Values : [ ] [ ] interface { } {
str2iface ( [ ] string { "caeast" } ) ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
2015-01-29 20:00:15 +00:00
// SHOW TAG VALUES FROM ... WITH KEY IN ... WHERE ...
{
q : ` SHOW TAG VALUES FROM cpu WITH KEY IN (host, region) WHERE region = 'uswest' ` ,
r : & influxdb . Results {
Results : [ ] * influxdb . Result {
2015-02-01 20:33:12 +00:00
{
2015-02-23 05:21:49 +00:00
Series : [ ] * influxql . Row {
2015-02-01 20:33:12 +00:00
{
2015-02-23 06:25:27 +00:00
Name : "hostTagValues" ,
Columns : [ ] string { "host" } ,
2015-01-29 20:00:15 +00:00
Values : [ ] [ ] interface { } {
str2iface ( [ ] string { "server01" } ) ,
2015-02-23 06:25:27 +00:00
} ,
} ,
{
Name : "regionTagValues" ,
Columns : [ ] string { "region" } ,
Values : [ ] [ ] interface { } {
2015-01-29 20:00:15 +00:00
str2iface ( [ ] string { "uswest" } ) ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
}
for i , tt := range tests {
query := map [ string ] string { "db" : "foo" , "q" : tt . q }
2015-01-30 22:31:31 +00:00
status , body = MustHTTP ( "GET" , s . URL + ` /query ` , query , nil , "" )
if status != http . StatusOK {
t . Logf ( "query #%d: %s" , i , tt . q )
t . Log ( body )
t . Errorf ( "unexpected status: %d" , status )
}
r := & influxdb . Results { }
if err := json . Unmarshal ( [ ] byte ( body ) , r ) ; err != nil {
t . Logf ( "query #%d: %s" , i , tt . q )
t . Log ( body )
t . Error ( err )
}
if ! reflect . DeepEqual ( tt . err , errstring ( r . Err ) ) {
2015-02-16 20:30:58 +00:00
t . Logf ( "query #%d: %s" , i , tt . q )
2015-01-30 22:31:31 +00:00
t . Errorf ( "%d. %s: error mismatch:\n exp=%s\n got=%s\n\n" , i , tt . q , tt . err , r . Err )
} else if tt . err == "" && ! reflect . DeepEqual ( tt . r , r ) {
2015-02-16 20:30:58 +00:00
t . Logf ( "query #%d: %s" , i , tt . q )
t . Logf ( "exp = %s" , mustMarshalJSON ( tt . r ) )
t . Logf ( "got = %s" , body )
2015-01-30 22:31:31 +00:00
t . Errorf ( "%d. %s: result mismatch:\n\nexp=%#v\n\ngot=%#v\n\n" , i , tt . q , tt . r , r )
}
}
}
func TestHandler_serveShowFieldKeys ( t * testing . T ) {
2015-02-05 22:54:32 +00:00
srvr := OpenAuthlessServer ( NewMessagingClient ( ) )
2015-01-30 22:31:31 +00:00
srvr . CreateDatabase ( "foo" )
srvr . CreateRetentionPolicy ( "foo" , influxdb . NewRetentionPolicy ( "bar" ) )
srvr . SetDefaultRetentionPolicy ( "foo" , "bar" )
s := NewHTTPServer ( srvr )
defer s . Close ( )
status , body := MustHTTP ( "POST" , s . URL + ` /write ` , nil , nil , ` { "database" : "foo" , "retentionPolicy" : "bar" , "points" : [
2015-02-23 22:37:10 +00:00
{ "name" : "cpu" , "tags" : { "host" : "server01" } , "timestamp" : "2009-11-10T23:00:00Z" , "fields" : { "field1" : 100 } } ,
{ "name" : "cpu" , "tags" : { "host" : "server01" , "region" : "uswest" } , "timestamp" : "2009-11-10T23:00:00Z" , "fields" : { "field1" : 200 , "field2" : 300 , "field3" : 400 } } ,
{ "name" : "cpu" , "tags" : { "host" : "server01" , "region" : "useast" } , "timestamp" : "2009-11-10T23:00:00Z" , "fields" : { "field1" : 200 , "field2" : 300 , "field3" : 400 } } ,
{ "name" : "cpu" , "tags" : { "host" : "server02" , "region" : "useast" } , "timestamp" : "2009-11-10T23:00:00Z" , "fields" : { "field1" : 200 , "field2" : 300 , "field3" : 400 } } ,
{ "name" : "gpu" , "tags" : { "host" : "server01" , "region" : "useast" } , "timestamp" : "2009-11-10T23:00:00Z" , "fields" : { "field4" : 200 , "field5" : 300 } } ,
{ "name" : "gpu" , "tags" : { "host" : "server03" , "region" : "caeast" } , "timestamp" : "2009-11-10T23:00:00Z" , "fields" : { "field6" : 200 , "field7" : 300 } }
2015-01-30 22:31:31 +00:00
] } ` )
if status != http . StatusOK {
t . Log ( body )
t . Fatalf ( "unexpected status after write: %d" , status )
}
var tests = [ ] struct {
q string
r * influxdb . Results
err string
} {
2015-02-16 20:30:58 +00:00
// SHOW FIELD KEYS
2015-01-30 22:31:31 +00:00
{
2015-02-16 20:30:58 +00:00
q : ` SHOW FIELD KEYS ` ,
2015-01-30 22:31:31 +00:00
r : & influxdb . Results {
Results : [ ] * influxdb . Result {
{
2015-02-23 05:21:49 +00:00
Series : [ ] * influxql . Row {
2015-01-30 22:31:31 +00:00
{
Name : "cpu" ,
Columns : [ ] string { "fieldKey" } ,
Values : [ ] [ ] interface { } {
str2iface ( [ ] string { "field1" } ) ,
str2iface ( [ ] string { "field2" } ) ,
str2iface ( [ ] string { "field3" } ) ,
} ,
} ,
{
Name : "gpu" ,
Columns : [ ] string { "fieldKey" } ,
Values : [ ] [ ] interface { } {
str2iface ( [ ] string { "field4" } ) ,
str2iface ( [ ] string { "field5" } ) ,
2015-02-16 20:30:58 +00:00
str2iface ( [ ] string { "field6" } ) ,
str2iface ( [ ] string { "field7" } ) ,
2015-01-30 22:31:31 +00:00
} ,
} ,
} ,
} ,
} ,
} ,
} ,
2015-02-21 21:49:38 +00:00
// SHOW FIELD KEYS FROM ...
{
q : ` SHOW FIELD KEYS FROM cpu ` ,
r : & influxdb . Results {
Results : [ ] * influxdb . Result {
{
2015-02-23 05:21:49 +00:00
Series : [ ] * influxql . Row {
2015-02-21 21:49:38 +00:00
{
Name : "cpu" ,
Columns : [ ] string { "fieldKey" } ,
Values : [ ] [ ] interface { } {
str2iface ( [ ] string { "field1" } ) ,
str2iface ( [ ] string { "field2" } ) ,
str2iface ( [ ] string { "field3" } ) ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
2015-01-30 22:31:31 +00:00
}
for i , tt := range tests {
query := map [ string ] string { "db" : "foo" , "q" : tt . q }
2015-01-29 20:00:15 +00:00
status , body = MustHTTP ( "GET" , s . URL + ` /query ` , query , nil , "" )
if status != http . StatusOK {
t . Logf ( "query #%d: %s" , i , tt . q )
t . Log ( body )
t . Errorf ( "unexpected status: %d" , status )
}
r := & influxdb . Results { }
if err := json . Unmarshal ( [ ] byte ( body ) , r ) ; err != nil {
t . Logf ( "query #%d: %s" , i , tt . q )
t . Log ( body )
t . Error ( err )
}
if ! reflect . DeepEqual ( tt . err , errstring ( r . Err ) ) {
2015-02-16 20:30:58 +00:00
t . Logf ( "query #%d: %s" , i , tt . q )
2015-01-29 01:26:15 +00:00
t . Errorf ( "%d. %s: error mismatch:\n exp=%s\n got=%s\n\n" , i , tt . q , tt . err , r . Err )
} else if tt . err == "" && ! reflect . DeepEqual ( tt . r , r ) {
2015-02-16 20:30:58 +00:00
t . Logf ( "query #%d: %s" , i , tt . q )
t . Logf ( "exp = %s" , mustMarshalJSON ( tt . r ) )
t . Logf ( "got = %s" , body )
2015-01-29 01:26:15 +00:00
t . Errorf ( "%d. %s: result mismatch:\n\nexp=%#v\n\ngot=%#v\n\n" , i , tt . q , tt . r , r )
}
}
}
2015-02-24 17:27:32 +00:00
func TestHandler_ProcessContinousQueries ( t * testing . T ) {
srvr := OpenAuthenticatedServer ( NewMessagingClient ( ) )
s := NewAuthenticatedHTTPServer ( srvr )
defer s . Close ( )
status , _ := MustHTTP ( "POST" , s . URL + ` /process_continuous_queries ` , nil , nil , "" )
if status != http . StatusAccepted {
t . Fatalf ( "unexpected status: %d" , status )
}
}
2015-01-29 19:28:13 +00:00
// batchWrite JSON Unmarshal tests
2015-01-05 23:47:12 +00:00
// Utility functions for this test suite.
2015-01-13 19:16:26 +00:00
func MustHTTP ( verb , path string , params , headers map [ string ] string , body string ) ( int , string ) {
req , err := http . NewRequest ( verb , path , bytes . NewBuffer ( [ ] byte ( body ) ) )
2014-11-20 18:05:53 +00:00
if err != nil {
panic ( err )
}
2015-01-05 23:47:12 +00:00
2015-01-13 19:16:26 +00:00
if params != nil {
q := url . Values { }
for k , v := range params {
q . Set ( k , v )
}
req . URL . RawQuery = q . Encode ( )
}
2015-01-05 23:47:12 +00:00
for k , v := range headers {
req . Header . Set ( k , v )
}
2015-01-06 00:01:24 +00:00
req . Header . Set ( "Content-Type" , "application/json" )
2014-12-23 06:18:05 +00:00
2014-11-20 18:05:53 +00:00
client := & http . Client { }
resp , err := client . Do ( req )
if err != nil {
panic ( err )
}
defer resp . Body . Close ( )
2014-12-23 06:18:05 +00:00
b , err := ioutil . ReadAll ( resp . Body )
return resp . StatusCode , strings . TrimRight ( string ( b ) , "\n" )
2014-11-20 18:05:53 +00:00
}
2014-12-29 23:12:51 +00:00
// 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
}
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
2015-01-20 17:50:13 +00:00
Handler * httpd . Handler
2014-11-19 17:12:46 +00:00
}
2014-11-20 16:02:21 +00:00
func NewHTTPServer ( s * Server ) * HTTPServer {
2015-01-22 01:13:51 +00:00
h := httpd . NewHandler ( s . Server , false , "X.X" )
2014-11-20 16:02:21 +00:00
return & HTTPServer { httptest . NewServer ( h ) , h }
2014-11-19 17:12:46 +00:00
}
2015-01-05 23:47:12 +00:00
func NewAuthenticatedHTTPServer ( s * Server ) * HTTPServer {
2015-01-22 01:13:51 +00:00
h := httpd . NewHandler ( s . Server , true , "X.X" )
2015-01-05 23:47:12 +00:00
return & HTTPServer { httptest . NewServer ( h ) , h }
}
2014-11-20 16:02:21 +00:00
func ( s * HTTPServer ) Close ( ) {
2014-11-19 17:12:46 +00:00
s . Server . Close ( )
}
2015-01-20 17:50:13 +00:00
// Server is a wrapping test struct for influxdb.Server.
type Server struct {
* influxdb . Server
}
// NewServer returns a new test server instance.
2015-02-05 22:54:32 +00:00
func NewServer ( ) * Server {
return & Server { influxdb . NewServer ( ) }
2015-01-20 17:50:13 +00:00
}
2015-02-05 22:54:32 +00:00
// OpenAuthenticatedServer returns a new, open test server instance with authentication enabled.
func OpenAuthenticatedServer ( client influxdb . MessagingClient ) * Server {
s := OpenUninitializedServer ( client )
2015-01-20 17:50:13 +00:00
if err := s . Initialize ( & url . URL { Host : "127.0.0.1:8080" } ) ; err != nil {
panic ( err . Error ( ) )
}
return s
}
2015-02-05 22:54:32 +00:00
// OpenAuthlessServer returns a new, open test server instance without authentication enabled.
func OpenAuthlessServer ( client influxdb . MessagingClient ) * Server {
s := OpenAuthenticatedServer ( client )
s . SetAuthenticationEnabled ( false )
return s
}
2015-01-30 15:43:29 +00:00
// Close shuts down the server and removes all temporary files.
func ( s * Server ) Close ( ) {
defer os . RemoveAll ( s . Path ( ) )
s . Server . Close ( )
}
// Restart stops and restarts the server.
func ( s * Server ) Restart ( ) {
path , client := s . Path ( ) , s . Client ( )
// Stop the server.
if err := s . Server . Close ( ) ; err != nil {
panic ( "close: " + err . Error ( ) )
}
// Open and reset the client.
if err := s . Server . Open ( path ) ; err != nil {
panic ( "open: " + err . Error ( ) )
}
if err := s . Server . SetClient ( client ) ; err != nil {
panic ( "client: " + err . Error ( ) )
}
}
2015-01-20 17:50:13 +00:00
// OpenUninitializedServer returns a new, uninitialized, open test server instance.
2015-02-05 22:54:32 +00:00
func OpenUninitializedServer ( client influxdb . MessagingClient ) * Server {
s := NewServer ( )
2015-01-20 17:50:13 +00:00
if err := s . Open ( tempfile ( ) ) ; err != nil {
panic ( err . Error ( ) )
}
if err := s . SetClient ( client ) ; err != nil {
panic ( err . Error ( ) )
}
return s
}
// TODO corylanou: evaluate how much of this should be in this package
// vs. how much should be a mocked out interface
// MessagingClient represents a test client for the messaging broker.
type MessagingClient struct {
index uint64
c chan * messaging . Message
2015-02-04 04:30:33 +00:00
mu sync . Mutex // Ensure all publishing is serialized.
2015-01-20 17:50:13 +00:00
PublishFunc func ( * messaging . Message ) ( uint64 , error )
2015-02-12 21:38:33 +00:00
CreateReplicaFunc func ( replicaID uint64 , connectURL * url . URL ) error
2015-01-20 17:50:13 +00:00
DeleteReplicaFunc func ( replicaID uint64 ) error
SubscribeFunc func ( replicaID , topicID uint64 ) error
UnsubscribeFunc func ( replicaID , topicID uint64 ) error
}
// NewMessagingClient returns a new instance of MessagingClient.
func NewMessagingClient ( ) * MessagingClient {
c := & MessagingClient { c : make ( chan * messaging . Message , 1 ) }
c . PublishFunc = c . send
2015-02-12 21:38:33 +00:00
c . CreateReplicaFunc = func ( replicaID uint64 , connectURL * url . URL ) error { return nil }
2015-01-20 17:50:13 +00:00
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 }
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 ) {
2015-02-04 04:30:33 +00:00
c . mu . Lock ( )
defer c . mu . Unlock ( )
2015-01-20 17:50:13 +00:00
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
}
// Creates a new replica with a given ID on the broker.
2015-02-12 21:38:33 +00:00
func ( c * MessagingClient ) CreateReplica ( replicaID uint64 , connectURL * url . URL ) error {
return c . CreateReplicaFunc ( replicaID , connectURL )
2015-01-20 17:50:13 +00:00
}
// Deletes an existing replica with a given ID from the broker.
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 )
}
// C returns a channel for streaming message.
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
}
2015-01-28 08:45:21 +00:00
// errstring converts an error to its string representation.
func errstring ( err error ) string {
if err != nil {
return err . Error ( )
}
return ""
}
2015-02-16 20:30:58 +00:00
// marshalJSON marshals input to a string of JSON or panics on error.
func mustMarshalJSON ( i interface { } ) string {
b , err := json . Marshal ( i )
if err != nil {
panic ( err )
}
return string ( b )
}