Add tests for admin info (#2553)

This commit is contained in:
Javier Adriel
2023-01-05 16:54:00 -06:00
committed by GitHub
parent 1cb2fca7a5
commit 756f0048f0
2 changed files with 132 additions and 48 deletions

View File

@@ -33,7 +33,6 @@ import (
"github.com/minio/console/models"
"github.com/minio/console/restapi/operations"
systemApi "github.com/minio/console/restapi/operations/system"
"github.com/minio/madmin-go/v2"
)
func registerAdminInfoHandlers(api *operations.ConsoleAPI) {
@@ -94,18 +93,13 @@ func GetAdminInfo(ctx context.Context, client MinioAdmin) (*UsageInfo, error) {
}
var usedSpace int64
for _, serv := range serverInfo.Servers {
for _, disk := range serv.Disks {
usedSpace += int64(disk.UsedSpace)
}
}
// serverArray contains the serverProperties which describe the servers in the network
var serverArray []*models.ServerProperties
for _, serv := range serverInfo.Servers {
drives := []*models.ServerDrives{}
for _, drive := range serv.Disks {
usedSpace += int64(drive.UsedSpace)
drives = append(drives, &models.ServerDrives{
State: drive.State,
UUID: drive.UUID,
@@ -905,7 +899,7 @@ func getAdminInfoResponse(session *models.Principal, params systemApi.AdminInfoP
return nil, ErrorWithContext(ctx, err)
}
sessionResp, err2 := getUsageWidgetsForDeployment(ctx, prometheusURL, mAdmin)
sessionResp, err2 := getUsageWidgetsForDeployment(ctx, prometheusURL, AdminClient{Client: mAdmin})
if err2 != nil {
return nil, ErrorWithContext(ctx, err2)
}
@@ -913,7 +907,7 @@ func getAdminInfoResponse(session *models.Principal, params systemApi.AdminInfoP
return sessionResp, nil
}
func getUsageWidgetsForDeployment(ctx context.Context, prometheusURL string, mAdmin *madmin.AdminClient) (*models.AdminInfoResponse, error) {
func getUsageWidgetsForDeployment(ctx context.Context, prometheusURL string, adminClient MinioAdmin) (*models.AdminInfoResponse, error) {
prometheusStatus := models.AdminInfoResponseAdvancedMetricsStatusAvailable
if prometheusURL == "" {
prometheusStatus = models.AdminInfoResponseAdvancedMetricsStatusNotConfigured
@@ -927,10 +921,6 @@ func getUsageWidgetsForDeployment(ctx context.Context, prometheusURL string, mAd
doneCh := make(chan error)
go func() {
defer close(doneCh)
// create a minioClient interface implementation
// defining the client to be used
adminClient := AdminClient{Client: mAdmin}
// serialize output
usage, err := GetAdminInfo(ctx, adminClient)
if err != nil {
@@ -1039,11 +1029,6 @@ func getAdminInfoWidgetResponse(params systemApi.DashboardWidgetDetailsParams) (
prometheusJobID := getPrometheusJobID()
prometheusExtraLabels := getPrometheusExtraLabels()
// We test if prometheus URL is reachable. this is meant to avoid unuseful calls and application hang.
if !testPrometheusURL(ctx, prometheusURL) {
return nil, ErrorWithContext(ctx, errors.New("Prometheus URL is unreachable"))
}
selector := fmt.Sprintf(`job="%s"`, prometheusJobID)
if strings.TrimSpace(prometheusExtraLabels) != "" {
selector = fmt.Sprintf(`job="%s",%s`, prometheusJobID, prometheusExtraLabels)
@@ -1052,6 +1037,10 @@ func getAdminInfoWidgetResponse(params systemApi.DashboardWidgetDetailsParams) (
}
func getWidgetDetails(ctx context.Context, prometheusURL string, selector string, widgetID int32, step *int32, start *int64, end *int64) (*models.WidgetDetails, *models.Error) {
// We test if prometheus URL is reachable. this is meant to avoid unuseful calls and application hang.
if !testPrometheusURL(ctx, prometheusURL) {
return nil, ErrorWithContext(ctx, errors.New("prometheus URL is unreachable"))
}
labelResultsCh := make(chan LabelResults)
for _, lbl := range labels {

View File

@@ -1,5 +1,5 @@
// This file is part of MinIO Console Server
// Copyright (c) 2021 MinIO, Inc.
// Copyright (c) 2023 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -18,42 +18,137 @@ package restapi
import (
"context"
"errors"
"net/http"
"net/http/httptest"
"os"
"testing"
"github.com/minio/console/models"
"github.com/minio/console/restapi/operations"
systemApi "github.com/minio/console/restapi/operations/system"
"github.com/minio/madmin-go/v2"
asrt "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"
)
func TestAdminInfo(t *testing.T) {
assert := asrt.New(t)
adminClient := adminClientMock{}
// Test-1 : getAdminInfo() returns proper information
type AdminInfoTestSuite struct {
suite.Suite
assert *assert.Assertions
currentServer string
isServerSet bool
isPrometheusRequest bool
server *httptest.Server
adminClient adminClientMock
}
func (suite *AdminInfoTestSuite) SetupSuite() {
suite.assert = assert.New(suite.T())
suite.adminClient = adminClientMock{}
minioServerInfoMock = func(ctx context.Context) (madmin.InfoMessage, error) {
return madmin.InfoMessage{
Buckets: madmin.Buckets{Count: 10},
Objects: madmin.Objects{Count: 10},
Usage: madmin.Usage{Size: 10},
Servers: []madmin.ServerProperties{{
Disks: []madmin.Disk{{}},
}},
Backend: map[string]interface{}{
"backendType": "mock",
"rrSCParity": 0.0,
"standardSCParity": 0.0,
},
}, nil
}
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
serverInfo, err := GetAdminInfo(ctx, adminClient)
assert.NotNil(serverInfo, "server info was returned nil")
if serverInfo != nil {
var actual64 int64 = 10
assert.Equal(serverInfo.Buckets, actual64, "Incorrect bucket count")
assert.Equal(serverInfo.Objects, actual64, "Incorrect object count")
assert.Equal(serverInfo.Usage, actual64, "Incorrect usage size")
}
assert.Nil(err, "Error should have been nil")
// Test-2 : getAdminInfo(ctx) fails for whatever reason
minioServerInfoMock = func(ctx context.Context) (madmin.InfoMessage, error) {
return madmin.InfoMessage{}, errors.New("some reason")
}
serverInfo, err = GetAdminInfo(ctx, adminClient)
assert.Nil(serverInfo, "server info was not returned nil")
assert.NotNil(err, "An error should have ben returned")
}
func (suite *AdminInfoTestSuite) SetupTest() {
suite.server = httptest.NewServer(http.HandlerFunc(suite.serverHandler))
suite.currentServer, suite.isServerSet = os.LookupEnv(ConsoleMinIOServer)
os.Setenv(ConsoleMinIOServer, suite.server.URL)
}
func (suite *AdminInfoTestSuite) serverHandler(w http.ResponseWriter, r *http.Request) {
if suite.isPrometheusRequest {
w.WriteHeader(200)
} else {
w.WriteHeader(400)
}
}
func (suite *AdminInfoTestSuite) TearDownSuite() {
}
func (suite *AdminInfoTestSuite) TearDownTest() {
if suite.isServerSet {
os.Setenv(ConsoleMinIOServer, suite.currentServer)
} else {
os.Unsetenv(ConsoleMinIOServer)
}
}
func (suite *AdminInfoTestSuite) TestRegisterAdminInfoHandlers() {
api := &operations.ConsoleAPI{}
suite.assertHandlersAreNil(api)
registerAdminInfoHandlers(api)
suite.assertHandlersAreNotNil(api)
}
func (suite *AdminInfoTestSuite) assertHandlersAreNil(api *operations.ConsoleAPI) {
suite.assert.Nil(api.SystemAdminInfoHandler)
suite.assert.Nil(api.SystemDashboardWidgetDetailsHandler)
}
func (suite *AdminInfoTestSuite) assertHandlersAreNotNil(api *operations.ConsoleAPI) {
suite.assert.NotNil(api.SystemAdminInfoHandler)
suite.assert.NotNil(api.SystemDashboardWidgetDetailsHandler)
}
func (suite *AdminInfoTestSuite) TestSystemAdminInfoHandlerWithError() {
params, api := suite.initSystemAdminInfoRequest()
response := api.SystemAdminInfoHandler.Handle(params, &models.Principal{})
_, ok := response.(*systemApi.AdminInfoDefault)
suite.assert.True(ok)
}
func (suite *AdminInfoTestSuite) initSystemAdminInfoRequest() (params systemApi.AdminInfoParams, api operations.ConsoleAPI) {
registerAdminInfoHandlers(&api)
params.HTTPRequest = &http.Request{}
defaultOnly := false
params.DefaultOnly = &defaultOnly
return params, api
}
func (suite *AdminInfoTestSuite) TestSystemDashboardWidgetDetailsHandlerWithError() {
params, api := suite.initSystemDashboardWidgetDetailsRequest()
response := api.SystemDashboardWidgetDetailsHandler.Handle(params, &models.Principal{})
_, ok := response.(*systemApi.DashboardWidgetDetailsDefault)
suite.assert.True(ok)
}
func (suite *AdminInfoTestSuite) initSystemDashboardWidgetDetailsRequest() (params systemApi.DashboardWidgetDetailsParams, api operations.ConsoleAPI) {
registerAdminInfoHandlers(&api)
params.HTTPRequest = &http.Request{}
return params, api
}
func (suite *AdminInfoTestSuite) TestGetUsageWidgetsForDeploymentWithoutError() {
ctx := context.Background()
suite.isPrometheusRequest = true
res, err := getUsageWidgetsForDeployment(ctx, suite.server.URL, suite.adminClient)
suite.assert.Nil(err)
suite.assert.NotNil(res)
suite.isPrometheusRequest = false
}
func (suite *AdminInfoTestSuite) TestGetWidgetDetailsWithoutError() {
ctx := context.Background()
suite.isPrometheusRequest = true
var step int32 = 1
var start int64
var end int64 = 1
res, err := getWidgetDetails(ctx, suite.server.URL, "mock", 1, &step, &start, &end)
suite.assert.Nil(err)
suite.assert.NotNil(res)
suite.isPrometheusRequest = false
}
func TestAdminInfo(t *testing.T) {
suite.Run(t, new(AdminInfoTestSuite))
}