649 lines
17 KiB
Go
649 lines
17 KiB
Go
package server
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"io/ioutil"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
"github.com/influxdata/httprouter"
|
|
"github.com/influxdata/influxdb/v2/chronograf"
|
|
"github.com/influxdata/influxdb/v2/chronograf/mocks"
|
|
)
|
|
|
|
func TestService_GetDatabases(t *testing.T) {
|
|
type fields struct {
|
|
SourcesStore chronograf.SourcesStore
|
|
ServersStore chronograf.ServersStore
|
|
LayoutsStore chronograf.LayoutsStore
|
|
UsersStore chronograf.UsersStore
|
|
DashboardsStore chronograf.DashboardsStore
|
|
TimeSeriesClient TimeSeriesClient
|
|
Logger chronograf.Logger
|
|
UseAuth bool
|
|
Databases chronograf.Databases
|
|
}
|
|
type args struct {
|
|
w http.ResponseWriter
|
|
r *http.Request
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
fields fields
|
|
args args
|
|
}{
|
|
// TODO: Add test cases.
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
h := &Service{
|
|
Store: &Store{
|
|
SourcesStore: tt.fields.SourcesStore,
|
|
ServersStore: tt.fields.ServersStore,
|
|
LayoutsStore: tt.fields.LayoutsStore,
|
|
UsersStore: tt.fields.UsersStore,
|
|
DashboardsStore: tt.fields.DashboardsStore,
|
|
},
|
|
TimeSeriesClient: tt.fields.TimeSeriesClient,
|
|
Logger: tt.fields.Logger,
|
|
UseAuth: tt.fields.UseAuth,
|
|
Databases: tt.fields.Databases,
|
|
}
|
|
h.GetDatabases(tt.args.w, tt.args.r)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestService_NewDatabase(t *testing.T) {
|
|
type fields struct {
|
|
SourcesStore chronograf.SourcesStore
|
|
ServersStore chronograf.ServersStore
|
|
LayoutsStore chronograf.LayoutsStore
|
|
UsersStore chronograf.UsersStore
|
|
DashboardsStore chronograf.DashboardsStore
|
|
TimeSeriesClient TimeSeriesClient
|
|
Logger chronograf.Logger
|
|
UseAuth bool
|
|
Databases chronograf.Databases
|
|
}
|
|
type args struct {
|
|
w http.ResponseWriter
|
|
r *http.Request
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
fields fields
|
|
args args
|
|
}{
|
|
// TODO: Add test cases.
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
h := &Service{
|
|
Store: &Store{
|
|
SourcesStore: tt.fields.SourcesStore,
|
|
ServersStore: tt.fields.ServersStore,
|
|
LayoutsStore: tt.fields.LayoutsStore,
|
|
UsersStore: tt.fields.UsersStore,
|
|
DashboardsStore: tt.fields.DashboardsStore,
|
|
},
|
|
TimeSeriesClient: tt.fields.TimeSeriesClient,
|
|
Logger: tt.fields.Logger,
|
|
UseAuth: tt.fields.UseAuth,
|
|
Databases: tt.fields.Databases,
|
|
}
|
|
h.NewDatabase(tt.args.w, tt.args.r)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestService_DropDatabase(t *testing.T) {
|
|
type fields struct {
|
|
SourcesStore chronograf.SourcesStore
|
|
ServersStore chronograf.ServersStore
|
|
LayoutsStore chronograf.LayoutsStore
|
|
UsersStore chronograf.UsersStore
|
|
DashboardsStore chronograf.DashboardsStore
|
|
TimeSeriesClient TimeSeriesClient
|
|
Logger chronograf.Logger
|
|
UseAuth bool
|
|
Databases chronograf.Databases
|
|
}
|
|
type args struct {
|
|
w http.ResponseWriter
|
|
r *http.Request
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
fields fields
|
|
args args
|
|
}{
|
|
// TODO: Add test cases.
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
h := &Service{
|
|
Store: &Store{
|
|
SourcesStore: tt.fields.SourcesStore,
|
|
ServersStore: tt.fields.ServersStore,
|
|
LayoutsStore: tt.fields.LayoutsStore,
|
|
UsersStore: tt.fields.UsersStore,
|
|
DashboardsStore: tt.fields.DashboardsStore,
|
|
},
|
|
TimeSeriesClient: tt.fields.TimeSeriesClient,
|
|
Logger: tt.fields.Logger,
|
|
UseAuth: tt.fields.UseAuth,
|
|
Databases: tt.fields.Databases,
|
|
}
|
|
h.DropDatabase(tt.args.w, tt.args.r)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestService_RetentionPolicies(t *testing.T) {
|
|
type fields struct {
|
|
SourcesStore chronograf.SourcesStore
|
|
ServersStore chronograf.ServersStore
|
|
LayoutsStore chronograf.LayoutsStore
|
|
UsersStore chronograf.UsersStore
|
|
DashboardsStore chronograf.DashboardsStore
|
|
TimeSeriesClient TimeSeriesClient
|
|
Logger chronograf.Logger
|
|
UseAuth bool
|
|
Databases chronograf.Databases
|
|
}
|
|
type args struct {
|
|
w http.ResponseWriter
|
|
r *http.Request
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
fields fields
|
|
args args
|
|
}{
|
|
// TODO: Add test cases.
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
h := &Service{
|
|
Store: &Store{
|
|
SourcesStore: tt.fields.SourcesStore,
|
|
ServersStore: tt.fields.ServersStore,
|
|
LayoutsStore: tt.fields.LayoutsStore,
|
|
UsersStore: tt.fields.UsersStore,
|
|
DashboardsStore: tt.fields.DashboardsStore,
|
|
},
|
|
TimeSeriesClient: tt.fields.TimeSeriesClient,
|
|
Logger: tt.fields.Logger,
|
|
UseAuth: tt.fields.UseAuth,
|
|
Databases: tt.fields.Databases,
|
|
}
|
|
h.RetentionPolicies(tt.args.w, tt.args.r)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestService_NewRetentionPolicy(t *testing.T) {
|
|
type fields struct {
|
|
SourcesStore chronograf.SourcesStore
|
|
ServersStore chronograf.ServersStore
|
|
LayoutsStore chronograf.LayoutsStore
|
|
UsersStore chronograf.UsersStore
|
|
DashboardsStore chronograf.DashboardsStore
|
|
TimeSeriesClient TimeSeriesClient
|
|
Logger chronograf.Logger
|
|
UseAuth bool
|
|
Databases chronograf.Databases
|
|
}
|
|
type args struct {
|
|
w http.ResponseWriter
|
|
r *http.Request
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
fields fields
|
|
args args
|
|
}{
|
|
// TODO: Add test cases.
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
h := &Service{
|
|
Store: &Store{
|
|
SourcesStore: tt.fields.SourcesStore,
|
|
ServersStore: tt.fields.ServersStore,
|
|
LayoutsStore: tt.fields.LayoutsStore,
|
|
UsersStore: tt.fields.UsersStore,
|
|
DashboardsStore: tt.fields.DashboardsStore,
|
|
},
|
|
TimeSeriesClient: tt.fields.TimeSeriesClient,
|
|
Logger: tt.fields.Logger,
|
|
UseAuth: tt.fields.UseAuth,
|
|
Databases: tt.fields.Databases,
|
|
}
|
|
h.NewRetentionPolicy(tt.args.w, tt.args.r)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestService_UpdateRetentionPolicy(t *testing.T) {
|
|
type fields struct {
|
|
SourcesStore chronograf.SourcesStore
|
|
ServersStore chronograf.ServersStore
|
|
LayoutsStore chronograf.LayoutsStore
|
|
UsersStore chronograf.UsersStore
|
|
DashboardsStore chronograf.DashboardsStore
|
|
TimeSeriesClient TimeSeriesClient
|
|
Logger chronograf.Logger
|
|
UseAuth bool
|
|
Databases chronograf.Databases
|
|
}
|
|
type args struct {
|
|
w http.ResponseWriter
|
|
r *http.Request
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
fields fields
|
|
args args
|
|
}{
|
|
// TODO: Add test cases.
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
h := &Service{
|
|
Store: &Store{
|
|
SourcesStore: tt.fields.SourcesStore,
|
|
ServersStore: tt.fields.ServersStore,
|
|
LayoutsStore: tt.fields.LayoutsStore,
|
|
UsersStore: tt.fields.UsersStore,
|
|
DashboardsStore: tt.fields.DashboardsStore,
|
|
},
|
|
TimeSeriesClient: tt.fields.TimeSeriesClient,
|
|
Logger: tt.fields.Logger,
|
|
UseAuth: tt.fields.UseAuth,
|
|
Databases: tt.fields.Databases,
|
|
}
|
|
h.UpdateRetentionPolicy(tt.args.w, tt.args.r)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestService_DropRetentionPolicy(t *testing.T) {
|
|
type fields struct {
|
|
SourcesStore chronograf.SourcesStore
|
|
ServersStore chronograf.ServersStore
|
|
LayoutsStore chronograf.LayoutsStore
|
|
UsersStore chronograf.UsersStore
|
|
DashboardsStore chronograf.DashboardsStore
|
|
TimeSeriesClient TimeSeriesClient
|
|
Logger chronograf.Logger
|
|
UseAuth bool
|
|
Databases chronograf.Databases
|
|
}
|
|
type args struct {
|
|
w http.ResponseWriter
|
|
r *http.Request
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
fields fields
|
|
args args
|
|
}{
|
|
// TODO: Add test cases.
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
h := &Service{
|
|
Store: &Store{
|
|
SourcesStore: tt.fields.SourcesStore,
|
|
ServersStore: tt.fields.ServersStore,
|
|
LayoutsStore: tt.fields.LayoutsStore,
|
|
UsersStore: tt.fields.UsersStore,
|
|
DashboardsStore: tt.fields.DashboardsStore,
|
|
},
|
|
TimeSeriesClient: tt.fields.TimeSeriesClient,
|
|
Logger: tt.fields.Logger,
|
|
UseAuth: tt.fields.UseAuth,
|
|
Databases: tt.fields.Databases,
|
|
}
|
|
h.DropRetentionPolicy(tt.args.w, tt.args.r)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestService_Measurements(t *testing.T) {
|
|
type fields struct {
|
|
SourcesStore chronograf.SourcesStore
|
|
Logger chronograf.Logger
|
|
Databases chronograf.Databases
|
|
}
|
|
type args struct {
|
|
queryParams map[string]string
|
|
}
|
|
type wants struct {
|
|
statusCode int
|
|
body string
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
fields fields
|
|
args args
|
|
wants wants
|
|
}{
|
|
{
|
|
name: "Gets 100 measurements when no limit or offset provided",
|
|
fields: fields{
|
|
SourcesStore: &mocks.SourcesStore{
|
|
GetF: func(ctx context.Context, srcID int) (chronograf.Source, error) {
|
|
return chronograf.Source{
|
|
ID: 0,
|
|
}, nil
|
|
},
|
|
},
|
|
Databases: &mocks.Databases{
|
|
ConnectF: func(context.Context, *chronograf.Source) error {
|
|
return nil
|
|
},
|
|
GetMeasurementsF: func(ctx context.Context, db string, limit, offset int) ([]chronograf.Measurement, error) {
|
|
return []chronograf.Measurement{
|
|
{
|
|
Name: "pineapple",
|
|
},
|
|
{
|
|
Name: "cubeapple",
|
|
},
|
|
{
|
|
Name: "pinecube",
|
|
},
|
|
}, nil
|
|
},
|
|
},
|
|
},
|
|
args: args{
|
|
queryParams: map[string]string{},
|
|
},
|
|
wants: wants{
|
|
statusCode: 200,
|
|
body: `{"measurements":[{"name":"pineapple"},{"name":"cubeapple"},{"name":"pinecube"}],"links":{"self":"/chronograf/v1/sources/0/dbs/pineapples/measurements?limit=100\u0026offset=0","first":"/chronograf/v1/sources/0/dbs/pineapples/measurements?limit=100\u0026offset=0","next":"/chronograf/v1/sources/0/dbs/pineapples/measurements?limit=100\u0026offset=100"}}
|
|
`,
|
|
},
|
|
},
|
|
{
|
|
name: "Fails when invalid limit value provided",
|
|
fields: fields{
|
|
SourcesStore: &mocks.SourcesStore{
|
|
GetF: func(ctx context.Context, srcID int) (chronograf.Source, error) {
|
|
return chronograf.Source{
|
|
ID: 0,
|
|
}, nil
|
|
},
|
|
},
|
|
},
|
|
args: args{
|
|
queryParams: map[string]string{
|
|
"limit": "joe",
|
|
},
|
|
},
|
|
wants: wants{
|
|
statusCode: 422,
|
|
body: `{"code":422,"message":"strconv.Atoi: parsing \"joe\": invalid syntax"}`,
|
|
},
|
|
},
|
|
{
|
|
name: "Fails when invalid offset value provided",
|
|
fields: fields{
|
|
SourcesStore: &mocks.SourcesStore{
|
|
GetF: func(ctx context.Context, srcID int) (chronograf.Source, error) {
|
|
return chronograf.Source{
|
|
ID: 0,
|
|
}, nil
|
|
},
|
|
},
|
|
},
|
|
args: args{
|
|
queryParams: map[string]string{
|
|
"offset": "bob",
|
|
},
|
|
},
|
|
wants: wants{
|
|
statusCode: 422,
|
|
body: `{"code":422,"message":"strconv.Atoi: parsing \"bob\": invalid syntax"}`,
|
|
},
|
|
},
|
|
{
|
|
name: "Overrides limit less than or equal to 0 with limit 100",
|
|
fields: fields{
|
|
SourcesStore: &mocks.SourcesStore{
|
|
GetF: func(ctx context.Context, srcID int) (chronograf.Source, error) {
|
|
return chronograf.Source{
|
|
ID: 0,
|
|
}, nil
|
|
},
|
|
},
|
|
Databases: &mocks.Databases{
|
|
ConnectF: func(context.Context, *chronograf.Source) error {
|
|
return nil
|
|
},
|
|
GetMeasurementsF: func(ctx context.Context, db string, limit, offset int) ([]chronograf.Measurement, error) {
|
|
return []chronograf.Measurement{
|
|
{
|
|
Name: "pineapple",
|
|
},
|
|
{
|
|
Name: "cubeapple",
|
|
},
|
|
{
|
|
Name: "pinecube",
|
|
},
|
|
}, nil
|
|
},
|
|
},
|
|
},
|
|
args: args{
|
|
queryParams: map[string]string{
|
|
"limit": "0",
|
|
},
|
|
},
|
|
wants: wants{
|
|
statusCode: 200,
|
|
body: `{"measurements":[{"name":"pineapple"},{"name":"cubeapple"},{"name":"pinecube"}],"links":{"self":"/chronograf/v1/sources/0/dbs/pineapples/measurements?limit=100\u0026offset=0","first":"/chronograf/v1/sources/0/dbs/pineapples/measurements?limit=100\u0026offset=0","next":"/chronograf/v1/sources/0/dbs/pineapples/measurements?limit=100\u0026offset=100"}}
|
|
`,
|
|
},
|
|
},
|
|
{
|
|
name: "Overrides offset less than 0 with offset 0",
|
|
fields: fields{
|
|
SourcesStore: &mocks.SourcesStore{
|
|
GetF: func(ctx context.Context, srcID int) (chronograf.Source, error) {
|
|
return chronograf.Source{
|
|
ID: 0,
|
|
}, nil
|
|
},
|
|
},
|
|
Databases: &mocks.Databases{
|
|
ConnectF: func(context.Context, *chronograf.Source) error {
|
|
return nil
|
|
},
|
|
GetMeasurementsF: func(ctx context.Context, db string, limit, offset int) ([]chronograf.Measurement, error) {
|
|
return []chronograf.Measurement{
|
|
{
|
|
Name: "pineapple",
|
|
},
|
|
{
|
|
Name: "cubeapple",
|
|
},
|
|
{
|
|
Name: "pinecube",
|
|
},
|
|
}, nil
|
|
},
|
|
},
|
|
},
|
|
args: args{
|
|
queryParams: map[string]string{
|
|
"offset": "-1337",
|
|
},
|
|
},
|
|
wants: wants{
|
|
statusCode: 200,
|
|
body: `{"measurements":[{"name":"pineapple"},{"name":"cubeapple"},{"name":"pinecube"}],"links":{"self":"/chronograf/v1/sources/0/dbs/pineapples/measurements?limit=100\u0026offset=0","first":"/chronograf/v1/sources/0/dbs/pineapples/measurements?limit=100\u0026offset=0","next":"/chronograf/v1/sources/0/dbs/pineapples/measurements?limit=100\u0026offset=100"}}
|
|
`,
|
|
},
|
|
},
|
|
{
|
|
name: "Provides a prev link when offset exceeds limit",
|
|
fields: fields{
|
|
SourcesStore: &mocks.SourcesStore{
|
|
GetF: func(ctx context.Context, srcID int) (chronograf.Source, error) {
|
|
return chronograf.Source{
|
|
ID: 0,
|
|
}, nil
|
|
},
|
|
},
|
|
Databases: &mocks.Databases{
|
|
ConnectF: func(context.Context, *chronograf.Source) error {
|
|
return nil
|
|
},
|
|
GetMeasurementsF: func(ctx context.Context, db string, limit, offset int) ([]chronograf.Measurement, error) {
|
|
return []chronograf.Measurement{
|
|
{
|
|
Name: "pineapple",
|
|
},
|
|
{
|
|
Name: "cubeapple",
|
|
},
|
|
{
|
|
Name: "pinecube",
|
|
},
|
|
{
|
|
Name: "billietta",
|
|
},
|
|
{
|
|
Name: "bobbetta",
|
|
},
|
|
{
|
|
Name: "bobcube",
|
|
},
|
|
}, nil
|
|
},
|
|
},
|
|
},
|
|
args: args{
|
|
queryParams: map[string]string{
|
|
"limit": "2",
|
|
"offset": "4",
|
|
},
|
|
},
|
|
wants: wants{
|
|
statusCode: 200,
|
|
body: `{"measurements":[{"name":"pineapple"},{"name":"cubeapple"},{"name":"pinecube"},{"name":"billietta"},{"name":"bobbetta"},{"name":"bobcube"}],"links":{"self":"/chronograf/v1/sources/0/dbs/pineapples/measurements?limit=2\u0026offset=4","first":"/chronograf/v1/sources/0/dbs/pineapples/measurements?limit=2\u0026offset=0","next":"/chronograf/v1/sources/0/dbs/pineapples/measurements?limit=2\u0026offset=6","prev":"/chronograf/v1/sources/0/dbs/pineapples/measurements?limit=2\u0026offset=2"}}
|
|
`,
|
|
},
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
logger := &chronograf.NoopLogger{}
|
|
h := &Service{
|
|
Store: &mocks.Store{
|
|
SourcesStore: tt.fields.SourcesStore,
|
|
},
|
|
Logger: logger,
|
|
Databases: tt.fields.Databases,
|
|
}
|
|
|
|
w := httptest.NewRecorder()
|
|
r := httptest.NewRequest(
|
|
"GET",
|
|
"http://any.url",
|
|
nil,
|
|
)
|
|
r = r.WithContext(context.WithValue(
|
|
context.TODO(),
|
|
httprouter.ParamsKey,
|
|
httprouter.Params{
|
|
{
|
|
Key: "id",
|
|
Value: "0",
|
|
},
|
|
{
|
|
Key: "db",
|
|
Value: "pineapples",
|
|
},
|
|
}))
|
|
|
|
q := r.URL.Query()
|
|
for key, value := range tt.args.queryParams {
|
|
q.Add(key, value)
|
|
}
|
|
r.URL.RawQuery = q.Encode()
|
|
|
|
h.Measurements(w, r)
|
|
|
|
resp := w.Result()
|
|
body, err := ioutil.ReadAll(resp.Body)
|
|
defer resp.Body.Close()
|
|
|
|
if err != nil {
|
|
t.Error("TestService_Measurements not able to retrieve body")
|
|
}
|
|
|
|
var msmts measurementsResponse
|
|
if err := json.Unmarshal(body, &msmts); err != nil {
|
|
t.Error("TestService_Measurements not able to unmarshal JSON response")
|
|
}
|
|
|
|
if tt.wants.statusCode != resp.StatusCode {
|
|
t.Errorf("%q. StatusCode:\nwant\n%v\ngot\n%v", tt.name, tt.wants.statusCode, resp.StatusCode)
|
|
}
|
|
|
|
if tt.wants.body != string(body) {
|
|
t.Errorf("%q. Body:\nwant\n*%s*\ngot\n*%s*", tt.name, tt.wants.body, string(body))
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestValidDatabaseRequest(t *testing.T) {
|
|
type args struct {
|
|
d *chronograf.Database
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
wantErr bool
|
|
}{
|
|
// TODO: Add test cases.
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if err := ValidDatabaseRequest(tt.args.d); (err != nil) != tt.wantErr {
|
|
t.Errorf("ValidDatabaseRequest() error = %v, wantErr %v", err, tt.wantErr)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestValidRetentionPolicyRequest(t *testing.T) {
|
|
type args struct {
|
|
rp *chronograf.RetentionPolicy
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
wantErr bool
|
|
}{
|
|
// TODO: Add test cases.
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if err := ValidRetentionPolicyRequest(tt.args.rp); (err != nil) != tt.wantErr {
|
|
t.Errorf("ValidRetentionPolicyRequest() error = %v, wantErr %v", err, tt.wantErr)
|
|
}
|
|
})
|
|
}
|
|
}
|