influxdb/chronograf/server/databases_test.go

649 lines
17 KiB
Go
Raw Normal View History

2017-03-24 16:58:57 +00:00
package server
import (
"context"
"encoding/json"
"io/ioutil"
2017-03-24 16:58:57 +00:00
"net/http"
"net/http/httptest"
2017-03-24 16:58:57 +00:00
"testing"
"github.com/influxdata/influxdb/chronograf"
"github.com/influxdata/influxdb/chronograf/mocks"
2018-07-25 18:38:51 +00:00
"github.com/julienschmidt/httprouter"
2017-03-24 16:58:57 +00:00
)
func TestService_GetDatabases(t *testing.T) {
type fields struct {
SourcesStore chronograf.SourcesStore
ServersStore chronograf.ServersStore
LayoutsStore chronograf.LayoutsStore
2017-03-24 16:58:57 +00:00
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.
2017-03-24 16:58:57 +00:00
}
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,
},
2017-03-24 16:58:57 +00:00
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
2017-03-24 16:58:57 +00:00
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.
2017-03-24 16:58:57 +00:00
}
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,
},
2017-03-24 16:58:57 +00:00
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
2017-03-24 16:58:57 +00:00
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.
2017-03-24 16:58:57 +00:00
}
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,
},
2017-03-24 16:58:57 +00:00
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
2017-03-24 16:58:57 +00:00
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.
2017-03-24 16:58:57 +00:00
}
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,
},
2017-03-24 16:58:57 +00:00
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
2017-03-24 16:58:57 +00:00
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.
2017-03-24 16:58:57 +00:00
}
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,
},
2017-03-24 16:58:57 +00:00
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
2017-03-24 16:58:57 +00:00
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.
2017-03-24 16:58:57 +00:00
}
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,
},
2017-03-24 16:58:57 +00:00
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
2017-03-24 16:58:57 +00:00
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.
2017-03-24 16:58:57 +00:00
}
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,
},
2017-03-24 16:58:57 +00:00
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) {
feat(vault): add vault implementation of secret service test(platform): run testcontainer integration tests for nightly release Integration tests for the vault secret service using testcontiners should not run along with unit tests, however, they should run on some regular schedule. This commit introduces `make test-integration` which runs integration tests for vault using testcontainers. The command introduced relies on docker being available on the host it is executed on. chore(platform): make go modules tidy chore: try to fix go mod chore(platform): remove explicit logrus dependency chore(platform): run go mod tidy chore(platform): replace github.com/Sirupsen/logrus with github.com/sirupsen/logrus chore(platform): update docker dependency feat(vault): add vault implementation of secret service test(platform): run testcontainer integration tests for nightly release Integration tests for the vault secret service using testcontiners should not run along with unit tests, however, they should run on some regular schedule. This commit introduces `make test-integration` which runs integration tests for vault using testcontainers. The command introduced relies on docker being available on the host it is executed on. chore(platform): make go modules tidy chore: try to fix go mod chore(platform): run go mod tidy feat(vault): add vault implementation of secret service chore(platform): make go modules tidy feat(platform): add Put/Patch/Delete methods on secret service feat(vault): add Put/Patch/Delete methods on vault secret service feat(http): add http handler methods for secret service feat(bolt): add Put/Delete/Patch methods to bolt secret service feat(testing): add tests for Put/Patch/Delete methods in secret service feat(mock): add mock secret service feat(http): add tests for secrets endpoints feat(http): update swagger for secrets endpoints chore: run go mod tidy
2018-11-16 16:45:00 +00:00
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,
)
2018-07-25 18:38:51 +00:00
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))
}
})
}
}
2017-03-24 16:58:57 +00:00
func TestValidDatabaseRequest(t *testing.T) {
type args struct {
d *chronograf.Database
}
tests := []struct {
name string
args args
wantErr bool
}{
// TODO: Add test cases.
2017-03-24 16:58:57 +00:00
}
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.
2017-03-24 16:58:57 +00:00
}
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)
}
})
}
}