updates for v0.4.0 release. Slight refactor/organization.

pull/237/head
Jason Kulatunga 2 years ago
parent 54178eaaf0
commit 381a6799cc

@ -10,6 +10,7 @@ import (
"io" "io"
"log" "log"
"os" "os"
"strings"
"time" "time"
utils "github.com/analogj/go-util/utils" utils "github.com/analogj/go-util/utils"
@ -113,7 +114,10 @@ OPTIONS:
} }
if c.IsSet("api-endpoint") { if c.IsSet("api-endpoint") {
config.Set("api.endpoint", c.String("api-endpoint")) //if the user is providing an api-endpoint with a basepath (eg. http://localhost:8080/scrutiny),
//we need to ensure the basepath has a trailing slash, otherwise the url.Parse() path concatenation doesnt work.
apiEndpoint := strings.TrimSuffix(c.String("api-endpoint"), "/") + "/"
config.Set("api.endpoint", apiEndpoint)
} }
collectorLogger := logrus.WithFields(logrus.Fields{ collectorLogger := logrus.WithFields(logrus.Fields{

@ -48,7 +48,7 @@ func (mc *MetricsCollector) Run() error {
} }
apiEndpoint, _ := url.Parse(mc.apiEndpoint.String()) apiEndpoint, _ := url.Parse(mc.apiEndpoint.String())
apiEndpoint.Path = "/api/devices/register" apiEndpoint, _ = apiEndpoint.Parse("api/devices/register") //this acts like filepath.Join()
deviceRespWrapper := new(models.DeviceWrapper) deviceRespWrapper := new(models.DeviceWrapper)
@ -73,6 +73,7 @@ func (mc *MetricsCollector) Run() error {
if !deviceRespWrapper.Success { if !deviceRespWrapper.Success {
mc.logger.Errorln("An error occurred while retrieving filtered devices") mc.logger.Errorln("An error occurred while retrieving filtered devices")
mc.logger.Debugln(deviceRespWrapper)
return errors.ApiServerCommunicationError("An error occurred while retrieving filtered devices") return errors.ApiServerCommunicationError("An error occurred while retrieving filtered devices")
} else { } else {
mc.logger.Debugln(deviceRespWrapper) mc.logger.Debugln(deviceRespWrapper)
@ -146,7 +147,7 @@ func (mc *MetricsCollector) Publish(deviceWWN string, payload []byte) error {
mc.logger.Infof("Publishing smartctl results for %s\n", deviceWWN) mc.logger.Infof("Publishing smartctl results for %s\n", deviceWWN)
apiEndpoint, _ := url.Parse(mc.apiEndpoint.String()) apiEndpoint, _ := url.Parse(mc.apiEndpoint.String())
apiEndpoint.Path = fmt.Sprintf("/api/device/%s/smart", strings.ToLower(deviceWWN)) apiEndpoint, _ = apiEndpoint.Parse(fmt.Sprintf("api/device/%s/smart", strings.ToLower(deviceWWN)))
resp, err := httpClient.Post(apiEndpoint.String(), "application/json", bytes.NewBuffer(payload)) resp, err := httpClient.Post(apiEndpoint.String(), "application/json", bytes.NewBuffer(payload))
if err != nil { if err != nil {

@ -0,0 +1,38 @@
package collector
import (
"github.com/stretchr/testify/require"
"net/url"
"testing"
)
func TestApiEndpointParse(t *testing.T) {
baseURL, _ := url.Parse("http://localhost:8080/")
url1, _ := baseURL.Parse("d/e")
require.Equal(t, "http://localhost:8080/d/e", url1.String())
url2, _ := baseURL.Parse("/d/e")
require.Equal(t, "http://localhost:8080/d/e", url2.String())
}
func TestApiEndpointParse_WithBasepathWithoutTrailingSlash(t *testing.T) {
baseURL, _ := url.Parse("http://localhost:8080/scrutiny")
//This testcase is unexpected and can cause issues. We need to ensure the apiEndpoint always has a trailing slash.
url1, _ := baseURL.Parse("d/e")
require.Equal(t, "http://localhost:8080/d/e", url1.String())
url2, _ := baseURL.Parse("/d/e")
require.Equal(t, "http://localhost:8080/d/e", url2.String())
}
func TestApiEndpointParse_WithBasepathWithTrailingSlash(t *testing.T) {
baseURL, _ := url.Parse("http://localhost:8080/scrutiny/")
url1, _ := baseURL.Parse("d/e")
require.Equal(t, "http://localhost:8080/scrutiny/d/e", url1.String())
url2, _ := baseURL.Parse("/d/e")
require.Equal(t, "http://localhost:8080/d/e", url2.String())
}

@ -20,7 +20,7 @@ COPY webapp/frontend /opt/scrutiny/src
RUN npm install -g @angular/cli@9.1.4 && \ RUN npm install -g @angular/cli@9.1.4 && \
mkdir -p /opt/scrutiny/dist && \ mkdir -p /opt/scrutiny/dist && \
npm install && \ npm install && \
ng build --output-path=/opt/scrutiny/dist --deploy-url="/web/" --base-href="/web/" --prod ng build --output-path=/opt/scrutiny/dist --prod
######## ########

@ -20,15 +20,20 @@ web:
listen: listen:
port: 8080 port: 8080
host: 0.0.0.0 host: 0.0.0.0
# if you're using a reverse proxy like apache/nginx, you can override this value to serve scrutiny on a subpath.
# eg. http://example.com/scrutiny/* vs http://example.com:8080
# see docs/TROUBLESHOOTING_REVERSE_PROXY.md
# basepath: `/scrutiny`
# leave empty unless behind a path prefixed proxy
basepath: ''
database: database:
# can also set absolute path here # can also set absolute path here
location: /opt/scrutiny/config/scrutiny.db location: /opt/scrutiny/config/scrutiny.db
src: src:
# the location on the filesystem where scrutiny javascript + css is located
frontend: frontend:
path: /opt/scrutiny/web path: /opt/scrutiny/web
# leave empty unless behind a path prefixed proxy
backend:
basepath: # if behind a path prefixed proxy set to path value with leading /
influxdb: influxdb:
host: 0.0.0.0 host: 0.0.0.0
port: 8086 port: 8086

@ -4,6 +4,7 @@ go 1.13
require ( require (
github.com/analogj/go-util v0.0.0-20190301173314-5295e364eb14 github.com/analogj/go-util v0.0.0-20190301173314-5295e364eb14
github.com/citilinkru/libudev v1.0.0
github.com/containrrr/shoutrrr v0.4.4 github.com/containrrr/shoutrrr v0.4.4
github.com/fatih/color v1.10.0 github.com/fatih/color v1.10.0
github.com/gin-gonic/gin v1.6.3 github.com/gin-gonic/gin v1.6.3

@ -30,8 +30,8 @@ func (c *configuration) Init() error {
//set defaults //set defaults
c.SetDefault("web.listen.port", "8080") c.SetDefault("web.listen.port", "8080")
c.SetDefault("web.listen.host", "0.0.0.0") c.SetDefault("web.listen.host", "0.0.0.0")
c.SetDefault("web.listen.basepath", "")
c.SetDefault("web.src.frontend.path", "/opt/scrutiny/web") c.SetDefault("web.src.frontend.path", "/opt/scrutiny/web")
c.SetDefault("web.src.backend.basepath", "")
c.SetDefault("web.database.location", "/opt/scrutiny/config/scrutiny.db") c.SetDefault("web.database.location", "/opt/scrutiny/config/scrutiny.db")
c.SetDefault("log.level", "INFO") c.SetDefault("log.level", "INFO")

@ -89,7 +89,7 @@ func LoggerMiddleware(logger logrus.FieldLogger) gin.HandlerFunc {
entry.Info(msg) entry.Info(msg)
} }
} }
if strings.HasPrefix(path, "/api/") { if strings.Contains(path, "/api/") {
//only debug log request/response from api endpoint. //only debug log request/response from api endpoint.
if len(reqBody) > 0 { if len(reqBody) > 0 {
entry.WithField("bodyType", "request").Debugln(reqBody) // Print request body entry.WithField("bodyType", "request").Debugln(reqBody) // Print request body

@ -27,8 +27,9 @@ func (ae *AppEngine) Setup(logger logrus.FieldLogger) *gin.Engine {
r.Use(middleware.ConfigMiddleware(ae.Config)) r.Use(middleware.ConfigMiddleware(ae.Config))
r.Use(gin.Recovery()) r.Use(gin.Recovery())
basePath := ae.Config.GetString("web.src.backend.basepath") basePath := ae.Config.GetString("web.listen.basepath")
logger.Debugf("basepath: %s", basePath) logger.Debugf("basepath: %s", basePath)
base := r.Group(basePath) base := r.Group(basePath)
{ {
api := base.Group("/api") api := base.Group("/api")
@ -40,12 +41,12 @@ func (ae *AppEngine) Setup(logger logrus.FieldLogger) *gin.Engine {
}) })
api.POST("/health/notify", handler.SendTestNotification) //check if notifications are configured correctly api.POST("/health/notify", handler.SendTestNotification) //check if notifications are configured correctly
api.POST("/devices/register", handler.RegisterDevices) //used by Collector to register new devices and retrieve filtered list api.POST("/devices/register", handler.RegisterDevices) //used by Collector to register new devices and retrieve filtered list
api.GET("/summary", handler.GetDevicesSummary) //used by Dashboard api.GET("/summary", handler.GetDevicesSummary) //used by Dashboard
api.GET("/summary/temp", handler.GetDevicesSummaryTempHistory) //used by Dashboard (Temperature history dropdown) api.GET("/summary/temp", handler.GetDevicesSummaryTempHistory) //used by Dashboard (Temperature history dropdown)
api.POST("/device/:wwn/smart", handler.UploadDeviceMetrics) //used by Collector to upload data api.POST("/device/:wwn/smart", handler.UploadDeviceMetrics) //used by Collector to upload data
api.POST("/device/:wwn/selftest", handler.UploadDeviceSelfTests) api.POST("/device/:wwn/selftest", handler.UploadDeviceSelfTests)
api.GET("/device/:wwn/details", handler.GetDeviceDetails) //used by Details api.GET("/device/:wwn/details", handler.GetDeviceDetails) //used by Details
} }
} }
@ -54,7 +55,7 @@ func (ae *AppEngine) Setup(logger logrus.FieldLogger) *gin.Engine {
//redirect base url to /web //redirect base url to /web
base.GET("/", func(c *gin.Context) { base.GET("/", func(c *gin.Context) {
c.Redirect(http.StatusFound, basePath + "/web") c.Redirect(http.StatusFound, basePath+"/web")
}) })
//catch-all, serve index page. //catch-all, serve index page.

@ -11,6 +11,7 @@ import (
"github.com/golang/mock/gomock" "github.com/golang/mock/gomock"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
"io" "io"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
@ -61,15 +62,36 @@ func helperReadSmartDataFileFixTimestamp(t *testing.T, smartDataFilepath string)
return bytes.NewReader(updatedSmartDataBytes) return bytes.NewReader(updatedSmartDataBytes)
} }
func TestHealthRoute(t *testing.T) { // Define the suite, and absorb the built-in basic suite
// functionality from testify - including a T() method which
// returns the current testing context
type ServerTestSuite struct {
suite.Suite
Basepath string
}
func TestServerTestSuite_WithEmptyBasePath(t *testing.T) {
emptyBasePathSuite := new(ServerTestSuite)
emptyBasePathSuite.Basepath = ""
suite.Run(t, emptyBasePathSuite)
}
func TestServerTestSuite_WithCustomBasePath(t *testing.T) {
emptyBasePathSuite := new(ServerTestSuite)
emptyBasePathSuite.Basepath = "/basepath"
suite.Run(t, emptyBasePathSuite)
}
func (suite *ServerTestSuite) TestHealthRoute() {
//setup //setup
parentPath, _ := ioutil.TempDir("", "") parentPath, _ := ioutil.TempDir("", "")
defer os.RemoveAll(parentPath) defer os.RemoveAll(parentPath)
mockCtrl := gomock.NewController(t) mockCtrl := gomock.NewController(suite.T())
defer mockCtrl.Finish() defer mockCtrl.Finish()
fakeConfig := mock_config.NewMockInterface(mockCtrl) fakeConfig := mock_config.NewMockInterface(mockCtrl)
fakeConfig.EXPECT().GetString("web.database.location").Return(path.Join(parentPath, "scrutiny_test.db")).AnyTimes() fakeConfig.EXPECT().GetString("web.database.location").Return(path.Join(parentPath, "scrutiny_test.db")).AnyTimes()
fakeConfig.EXPECT().GetString("web.src.frontend.path").Return(parentPath).AnyTimes() fakeConfig.EXPECT().GetString("web.src.frontend.path").Return(parentPath).AnyTimes()
fakeConfig.EXPECT().GetString("web.listen.basepath").Return(suite.Basepath).AnyTimes()
fakeConfig.EXPECT().GetString("web.influxdb.port").Return("8086").AnyTimes() fakeConfig.EXPECT().GetString("web.influxdb.port").Return("8086").AnyTimes()
fakeConfig.EXPECT().IsSet("web.influxdb.token").Return(true).AnyTimes() fakeConfig.EXPECT().IsSet("web.influxdb.token").Return(true).AnyTimes()
@ -90,53 +112,26 @@ func TestHealthRoute(t *testing.T) {
router := ae.Setup(logrus.New()) router := ae.Setup(logrus.New())
var basePathTestCases = []string{ //test
emptyBasePath, w := httptest.NewRecorder()
notEmptyBasePath, req, _ := http.NewRequest("GET", suite.Basepath+"/api/health", nil)
} router.ServeHTTP(w, req)
func TestHealthRoute(t *testing.T) { //assert
for _, basePath := range basePathTestCases { require.Equal(suite.T(), 200, w.Code)
t.Run(fmt.Sprintf(`with basePath "%s"`, basePath), func (tt *testing.T) { require.Equal(suite.T(), "{\"success\":true}", w.Body.String())
//setup
parentPath, _ := ioutil.TempDir("", "")
mockCtrl := gomock.NewController(tt)
fakeConfig := mock_config.NewMockInterface(mockCtrl)
fakeConfig.EXPECT().GetString("web.database.location").Return(path.Join(parentPath, "scrutiny_test.db")).AnyTimes()
fakeConfig.EXPECT().GetString("web.src.frontend.path").Return(parentPath).AnyTimes()
fakeConfig.EXPECT().GetString("web.src.backend.basepath").Return(basePath).AnyTimes()
ae := web.AppEngine{
Config: fakeConfig,
}
router := ae.Setup(logrus.New())
//test
w := httptest.NewRecorder()
req, _ := http.NewRequest("GET", basePath + "/api/health", nil)
router.ServeHTTP(w, req)
//assert
require.Equal(tt, 200, w.Code)
require.Equal(tt, "{\"success\":true}", w.Body.String())
// tear down
mockCtrl.Finish()
os.RemoveAll(parentPath)
})
}
} }
func TestRegisterDevicesRoute(t *testing.T) { func (suite *ServerTestSuite) TestRegisterDevicesRoute() {
//setup //setup
parentPath, _ := ioutil.TempDir("", "") parentPath, _ := ioutil.TempDir("", "")
defer os.RemoveAll(parentPath) defer os.RemoveAll(parentPath)
mockCtrl := gomock.NewController(t) mockCtrl := gomock.NewController(suite.T())
defer mockCtrl.Finish() defer mockCtrl.Finish()
fakeConfig := mock_config.NewMockInterface(mockCtrl) fakeConfig := mock_config.NewMockInterface(mockCtrl)
fakeConfig.EXPECT().GetString("web.database.location").Return(path.Join(parentPath, "scrutiny_test.db")).AnyTimes() fakeConfig.EXPECT().GetString("web.database.location").Return(path.Join(parentPath, "scrutiny_test.db")).AnyTimes()
fakeConfig.EXPECT().GetString("web.src.frontend.path").Return(parentPath).AnyTimes() fakeConfig.EXPECT().GetString("web.src.frontend.path").Return(parentPath).AnyTimes()
fakeConfig.EXPECT().GetString("web.listen.basepath").Return(suite.Basepath).AnyTimes()
fakeConfig.EXPECT().GetString("web.influxdb.port").Return("8086").AnyTimes() fakeConfig.EXPECT().GetString("web.influxdb.port").Return("8086").AnyTimes()
fakeConfig.EXPECT().IsSet("web.influxdb.token").Return(true).AnyTimes() fakeConfig.EXPECT().IsSet("web.influxdb.token").Return(true).AnyTimes()
fakeConfig.EXPECT().GetString("web.influxdb.token").Return("my-super-secret-auth-token").AnyTimes() fakeConfig.EXPECT().GetString("web.influxdb.token").Return("my-super-secret-auth-token").AnyTimes()
@ -153,17 +148,29 @@ func TestRegisterDevicesRoute(t *testing.T) {
ae := web.AppEngine{ ae := web.AppEngine{
Config: fakeConfig, Config: fakeConfig,
} }
router := ae.Setup(logrus.New())
file, err := os.Open("testdata/register-devices-req.json")
require.NoError(suite.T(), err)
//test
w := httptest.NewRecorder()
req, _ := http.NewRequest("POST", suite.Basepath+"/api/devices/register", file)
router.ServeHTTP(w, req)
//assert
require.Equal(suite.T(), 200, w.Code)
} }
func TestUploadDeviceMetricsRoute(t *testing.T) { func (suite *ServerTestSuite) TestUploadDeviceMetricsRoute() {
//setup //setup
parentPath, _ := ioutil.TempDir("", "") parentPath, _ := ioutil.TempDir("", "")
defer os.RemoveAll(parentPath) defer os.RemoveAll(parentPath)
mockCtrl := gomock.NewController(t) mockCtrl := gomock.NewController(suite.T())
defer mockCtrl.Finish() defer mockCtrl.Finish()
fakeConfig := mock_config.NewMockInterface(mockCtrl) fakeConfig := mock_config.NewMockInterface(mockCtrl)
fakeConfig.EXPECT().GetString("web.database.location").AnyTimes().Return(path.Join(parentPath, "scrutiny_test.db")) fakeConfig.EXPECT().GetString("web.database.location").AnyTimes().Return(path.Join(parentPath, "scrutiny_test.db"))
fakeConfig.EXPECT().GetString("web.src.frontend.path").AnyTimes().Return(parentPath) fakeConfig.EXPECT().GetString("web.src.frontend.path").AnyTimes().Return(parentPath)
fakeConfig.EXPECT().GetString("web.listen.basepath").Return(suite.Basepath).AnyTimes()
fakeConfig.EXPECT().GetString("web.influxdb.port").Return("8086").AnyTimes() fakeConfig.EXPECT().GetString("web.influxdb.port").Return("8086").AnyTimes()
fakeConfig.EXPECT().IsSet("web.influxdb.token").Return(true).AnyTimes() fakeConfig.EXPECT().IsSet("web.influxdb.token").Return(true).AnyTimes()
fakeConfig.EXPECT().GetString("web.influxdb.token").Return("my-super-secret-auth-token").AnyTimes() fakeConfig.EXPECT().GetString("web.influxdb.token").Return("my-super-secret-auth-token").AnyTimes()
@ -182,35 +189,36 @@ func TestUploadDeviceMetricsRoute(t *testing.T) {
} }
router := ae.Setup(logrus.New()) router := ae.Setup(logrus.New())
devicesfile, err := os.Open("testdata/register-devices-single-req.json") devicesfile, err := os.Open("testdata/register-devices-single-req.json")
require.NoError(t, err) require.NoError(suite.T(), err)
metricsfile := helperReadSmartDataFileFixTimestamp(t, "testdata/upload-device-metrics-req.json") metricsfile := helperReadSmartDataFileFixTimestamp(suite.T(), "testdata/upload-device-metrics-req.json")
//test //test
wr := httptest.NewRecorder() wr := httptest.NewRecorder()
req, _ := http.NewRequest("POST", "/api/devices/register", devicesfile) req, _ := http.NewRequest("POST", suite.Basepath+"/api/devices/register", devicesfile)
router.ServeHTTP(wr, req) router.ServeHTTP(wr, req)
require.Equal(t, 200, wr.Code) require.Equal(suite.T(), 200, wr.Code)
mr := httptest.NewRecorder() mr := httptest.NewRecorder()
req, _ = http.NewRequest("POST", "/api/device/0x5000cca264eb01d7/smart", metricsfile) req, _ = http.NewRequest("POST", suite.Basepath+"/api/device/0x5000cca264eb01d7/smart", metricsfile)
router.ServeHTTP(mr, req) router.ServeHTTP(mr, req)
require.Equal(t, 200, mr.Code) require.Equal(suite.T(), 200, mr.Code)
//assert //assert
} }
func TestPopulateMultiple(t *testing.T) { func (suite *ServerTestSuite) TestPopulateMultiple() {
//setup //setup
parentPath, _ := ioutil.TempDir("", "") parentPath, _ := ioutil.TempDir("", "")
defer os.RemoveAll(parentPath) defer os.RemoveAll(parentPath)
mockCtrl := gomock.NewController(t) mockCtrl := gomock.NewController(suite.T())
defer mockCtrl.Finish() defer mockCtrl.Finish()
fakeConfig := mock_config.NewMockInterface(mockCtrl) fakeConfig := mock_config.NewMockInterface(mockCtrl)
//fakeConfig.EXPECT().GetString("web.database.location").AnyTimes().Return("testdata/scrutiny_test.db") //fakeConfig.EXPECT().GetString("web.database.location").AnyTimes().Return("testdata/scrutiny_test.db")
fakeConfig.EXPECT().GetStringSlice("notify.urls").Return([]string{}).AnyTimes() fakeConfig.EXPECT().GetStringSlice("notify.urls").Return([]string{}).AnyTimes()
fakeConfig.EXPECT().GetString("web.database.location").AnyTimes().Return(path.Join(parentPath, "scrutiny_test.db")) fakeConfig.EXPECT().GetString("web.database.location").AnyTimes().Return(path.Join(parentPath, "scrutiny_test.db"))
fakeConfig.EXPECT().GetString("web.src.frontend.path").AnyTimes().Return(parentPath) fakeConfig.EXPECT().GetString("web.src.frontend.path").AnyTimes().Return(parentPath)
fakeConfig.EXPECT().GetString("web.listen.basepath").Return(suite.Basepath).AnyTimes()
fakeConfig.EXPECT().GetString("web.influxdb.port").Return("8086").AnyTimes() fakeConfig.EXPECT().GetString("web.influxdb.port").Return("8086").AnyTimes()
fakeConfig.EXPECT().IsSet("web.influxdb.token").Return(true).AnyTimes() fakeConfig.EXPECT().IsSet("web.influxdb.token").Return(true).AnyTimes()
fakeConfig.EXPECT().GetString("web.influxdb.token").Return("my-super-secret-auth-token").AnyTimes() fakeConfig.EXPECT().GetString("web.influxdb.token").Return("my-super-secret-auth-token").AnyTimes()
@ -229,44 +237,44 @@ func TestPopulateMultiple(t *testing.T) {
} }
router := ae.Setup(logrus.New()) router := ae.Setup(logrus.New())
devicesfile, err := os.Open("testdata/register-devices-req.json") devicesfile, err := os.Open("testdata/register-devices-req.json")
require.NoError(t, err) require.NoError(suite.T(), err)
metricsfile := helperReadSmartDataFileFixTimestamp(t, "../models/testdata/smart-ata.json") metricsfile := helperReadSmartDataFileFixTimestamp(suite.T(), "../models/testdata/smart-ata.json")
failfile := helperReadSmartDataFileFixTimestamp(t, "../models/testdata/smart-fail2.json") failfile := helperReadSmartDataFileFixTimestamp(suite.T(), "../models/testdata/smart-fail2.json")
nvmefile := helperReadSmartDataFileFixTimestamp(t, "../models/testdata/smart-nvme.json") nvmefile := helperReadSmartDataFileFixTimestamp(suite.T(), "../models/testdata/smart-nvme.json")
scsifile := helperReadSmartDataFileFixTimestamp(t, "../models/testdata/smart-scsi.json") scsifile := helperReadSmartDataFileFixTimestamp(suite.T(), "../models/testdata/smart-scsi.json")
scsi2file := helperReadSmartDataFileFixTimestamp(t, "../models/testdata/smart-scsi2.json") scsi2file := helperReadSmartDataFileFixTimestamp(suite.T(), "../models/testdata/smart-scsi2.json")
//test //test
wr := httptest.NewRecorder() wr := httptest.NewRecorder()
req, _ := http.NewRequest("POST", "/api/devices/register", devicesfile) req, _ := http.NewRequest("POST", suite.Basepath+"/api/devices/register", devicesfile)
router.ServeHTTP(wr, req) router.ServeHTTP(wr, req)
require.Equal(t, 200, wr.Code) require.Equal(suite.T(), 200, wr.Code)
mr := httptest.NewRecorder() mr := httptest.NewRecorder()
req, _ = http.NewRequest("POST", "/api/device/0x5000cca264eb01d7/smart", metricsfile) req, _ = http.NewRequest("POST", suite.Basepath+"/api/device/0x5000cca264eb01d7/smart", metricsfile)
router.ServeHTTP(mr, req) router.ServeHTTP(mr, req)
require.Equal(t, 200, mr.Code) require.Equal(suite.T(), 200, mr.Code)
fr := httptest.NewRecorder() fr := httptest.NewRecorder()
req, _ = http.NewRequest("POST", "/api/device/0x5000cca264ec3183/smart", failfile) req, _ = http.NewRequest("POST", suite.Basepath+"/api/device/0x5000cca264ec3183/smart", failfile)
router.ServeHTTP(fr, req) router.ServeHTTP(fr, req)
require.Equal(t, 200, fr.Code) require.Equal(suite.T(), 200, fr.Code)
nr := httptest.NewRecorder() nr := httptest.NewRecorder()
req, _ = http.NewRequest("POST", "/api/device/0x5002538e40a22954/smart", nvmefile) req, _ = http.NewRequest("POST", suite.Basepath+"/api/device/0x5002538e40a22954/smart", nvmefile)
router.ServeHTTP(nr, req) router.ServeHTTP(nr, req)
require.Equal(t, 200, nr.Code) require.Equal(suite.T(), 200, nr.Code)
sr := httptest.NewRecorder() sr := httptest.NewRecorder()
req, _ = http.NewRequest("POST", "/api/device/0x5000cca252c859cc/smart", scsifile) req, _ = http.NewRequest("POST", suite.Basepath+"/api/device/0x5000cca252c859cc/smart", scsifile)
router.ServeHTTP(sr, req) router.ServeHTTP(sr, req)
require.Equal(t, 200, sr.Code) require.Equal(suite.T(), 200, sr.Code)
s2r := httptest.NewRecorder() s2r := httptest.NewRecorder()
req, _ = http.NewRequest("POST", "/api/device/0x5000cca264ebc248/smart", scsi2file) req, _ = http.NewRequest("POST", suite.Basepath+"/api/device/0x5000cca264ebc248/smart", scsi2file)
router.ServeHTTP(s2r, req) router.ServeHTTP(s2r, req)
require.Equal(t, 200, s2r.Code) require.Equal(suite.T(), 200, s2r.Code)
//assert //assert
} }
@ -296,15 +304,16 @@ func TestPopulateMultiple(t *testing.T) {
// require.Equal(t, 200, wr.Code) // require.Equal(t, 200, wr.Code)
//} //}
func TestSendTestNotificationRoute_WebhookFailure(t *testing.T) { func (suite *ServerTestSuite) TestSendTestNotificationRoute_WebhookFailure() {
//setup //setup
parentPath, _ := ioutil.TempDir("", "") parentPath, _ := ioutil.TempDir("", "")
defer os.RemoveAll(parentPath) defer os.RemoveAll(parentPath)
mockCtrl := gomock.NewController(t) mockCtrl := gomock.NewController(suite.T())
defer mockCtrl.Finish() defer mockCtrl.Finish()
fakeConfig := mock_config.NewMockInterface(mockCtrl) fakeConfig := mock_config.NewMockInterface(mockCtrl)
fakeConfig.EXPECT().GetString("web.database.location").AnyTimes().Return(path.Join(parentPath, "scrutiny_test.db")) fakeConfig.EXPECT().GetString("web.database.location").AnyTimes().Return(path.Join(parentPath, "scrutiny_test.db"))
fakeConfig.EXPECT().GetString("web.src.frontend.path").AnyTimes().Return(parentPath) fakeConfig.EXPECT().GetString("web.src.frontend.path").AnyTimes().Return(parentPath)
fakeConfig.EXPECT().GetString("web.listen.basepath").Return(suite.Basepath).AnyTimes()
fakeConfig.EXPECT().GetString("web.influxdb.port").Return("8086").AnyTimes() fakeConfig.EXPECT().GetString("web.influxdb.port").Return("8086").AnyTimes()
fakeConfig.EXPECT().IsSet("web.influxdb.token").Return(true).AnyTimes() fakeConfig.EXPECT().IsSet("web.influxdb.token").Return(true).AnyTimes()
fakeConfig.EXPECT().GetString("web.influxdb.token").Return("my-super-secret-auth-token").AnyTimes() fakeConfig.EXPECT().GetString("web.influxdb.token").Return("my-super-secret-auth-token").AnyTimes()
@ -322,17 +331,27 @@ func TestSendTestNotificationRoute_WebhookFailure(t *testing.T) {
ae := web.AppEngine{ ae := web.AppEngine{
Config: fakeConfig, Config: fakeConfig,
} }
router := ae.Setup(logrus.New())
//test
wr := httptest.NewRecorder()
req, _ := http.NewRequest("POST", suite.Basepath+"/api/health/notify", strings.NewReader("{}"))
router.ServeHTTP(wr, req)
//assert
require.Equal(suite.T(), 500, wr.Code)
} }
func TestSendTestNotificationRoute_ScriptFailure(t *testing.T) { func (suite *ServerTestSuite) TestSendTestNotificationRoute_ScriptFailure() {
//setup //setup
parentPath, _ := ioutil.TempDir("", "") parentPath, _ := ioutil.TempDir("", "")
defer os.RemoveAll(parentPath) defer os.RemoveAll(parentPath)
mockCtrl := gomock.NewController(t) mockCtrl := gomock.NewController(suite.T())
defer mockCtrl.Finish() defer mockCtrl.Finish()
fakeConfig := mock_config.NewMockInterface(mockCtrl) fakeConfig := mock_config.NewMockInterface(mockCtrl)
fakeConfig.EXPECT().GetString("web.database.location").AnyTimes().Return(path.Join(parentPath, "scrutiny_test.db")) fakeConfig.EXPECT().GetString("web.database.location").AnyTimes().Return(path.Join(parentPath, "scrutiny_test.db"))
fakeConfig.EXPECT().GetString("web.src.frontend.path").AnyTimes().Return(parentPath) fakeConfig.EXPECT().GetString("web.src.frontend.path").AnyTimes().Return(parentPath)
fakeConfig.EXPECT().GetString("web.listen.basepath").Return(suite.Basepath).AnyTimes()
fakeConfig.EXPECT().GetString("web.influxdb.port").Return("8086").AnyTimes() fakeConfig.EXPECT().GetString("web.influxdb.port").Return("8086").AnyTimes()
fakeConfig.EXPECT().IsSet("web.influxdb.token").Return(true).AnyTimes() fakeConfig.EXPECT().IsSet("web.influxdb.token").Return(true).AnyTimes()
fakeConfig.EXPECT().GetString("web.influxdb.token").Return("my-super-secret-auth-token").AnyTimes() fakeConfig.EXPECT().GetString("web.influxdb.token").Return("my-super-secret-auth-token").AnyTimes()
@ -350,17 +369,27 @@ func TestSendTestNotificationRoute_ScriptFailure(t *testing.T) {
ae := web.AppEngine{ ae := web.AppEngine{
Config: fakeConfig, Config: fakeConfig,
} }
router := ae.Setup(logrus.New())
//test
wr := httptest.NewRecorder()
req, _ := http.NewRequest("POST", suite.Basepath+"/api/health/notify", strings.NewReader("{}"))
router.ServeHTTP(wr, req)
//assert
require.Equal(suite.T(), 500, wr.Code)
} }
func TestSendTestNotificationRoute_ScriptSuccess(t *testing.T) { func (suite *ServerTestSuite) TestSendTestNotificationRoute_ScriptSuccess() {
//setup //setup
parentPath, _ := ioutil.TempDir("", "") parentPath, _ := ioutil.TempDir("", "")
defer os.RemoveAll(parentPath) defer os.RemoveAll(parentPath)
mockCtrl := gomock.NewController(t) mockCtrl := gomock.NewController(suite.T())
defer mockCtrl.Finish() defer mockCtrl.Finish()
fakeConfig := mock_config.NewMockInterface(mockCtrl) fakeConfig := mock_config.NewMockInterface(mockCtrl)
fakeConfig.EXPECT().GetString("web.database.location").AnyTimes().Return(path.Join(parentPath, "scrutiny_test.db")) fakeConfig.EXPECT().GetString("web.database.location").AnyTimes().Return(path.Join(parentPath, "scrutiny_test.db"))
fakeConfig.EXPECT().GetString("web.src.frontend.path").AnyTimes().Return(parentPath) fakeConfig.EXPECT().GetString("web.src.frontend.path").AnyTimes().Return(parentPath)
fakeConfig.EXPECT().GetString("web.listen.basepath").Return(suite.Basepath).AnyTimes()
fakeConfig.EXPECT().GetString("web.influxdb.port").Return("8086").AnyTimes() fakeConfig.EXPECT().GetString("web.influxdb.port").Return("8086").AnyTimes()
fakeConfig.EXPECT().IsSet("web.influxdb.token").Return(true).AnyTimes() fakeConfig.EXPECT().IsSet("web.influxdb.token").Return(true).AnyTimes()
fakeConfig.EXPECT().GetString("web.influxdb.token").Return("my-super-secret-auth-token").AnyTimes() fakeConfig.EXPECT().GetString("web.influxdb.token").Return("my-super-secret-auth-token").AnyTimes()
@ -378,17 +407,27 @@ func TestSendTestNotificationRoute_ScriptSuccess(t *testing.T) {
ae := web.AppEngine{ ae := web.AppEngine{
Config: fakeConfig, Config: fakeConfig,
} }
router := ae.Setup(logrus.New())
//test
wr := httptest.NewRecorder()
req, _ := http.NewRequest("POST", suite.Basepath+"/api/health/notify", strings.NewReader("{}"))
router.ServeHTTP(wr, req)
//assert
require.Equal(suite.T(), 200, wr.Code)
} }
func TestSendTestNotificationRoute_ShoutrrrFailure(t *testing.T) { func (suite *ServerTestSuite) TestSendTestNotificationRoute_ShoutrrrFailure() {
//setup //setup
parentPath, _ := ioutil.TempDir("", "") parentPath, _ := ioutil.TempDir("", "")
defer os.RemoveAll(parentPath) defer os.RemoveAll(parentPath)
mockCtrl := gomock.NewController(t) mockCtrl := gomock.NewController(suite.T())
defer mockCtrl.Finish() defer mockCtrl.Finish()
fakeConfig := mock_config.NewMockInterface(mockCtrl) fakeConfig := mock_config.NewMockInterface(mockCtrl)
fakeConfig.EXPECT().GetString("web.database.location").AnyTimes().Return(path.Join(parentPath, "scrutiny_test.db")) fakeConfig.EXPECT().GetString("web.database.location").AnyTimes().Return(path.Join(parentPath, "scrutiny_test.db"))
fakeConfig.EXPECT().GetString("web.src.frontend.path").AnyTimes().Return(parentPath) fakeConfig.EXPECT().GetString("web.src.frontend.path").AnyTimes().Return(parentPath)
fakeConfig.EXPECT().GetString("web.listen.basepath").Return(suite.Basepath).AnyTimes()
fakeConfig.EXPECT().GetString("web.influxdb.port").Return("8086").AnyTimes() fakeConfig.EXPECT().GetString("web.influxdb.port").Return("8086").AnyTimes()
fakeConfig.EXPECT().IsSet("web.influxdb.token").Return(true).AnyTimes() fakeConfig.EXPECT().IsSet("web.influxdb.token").Return(true).AnyTimes()
fakeConfig.EXPECT().GetString("web.influxdb.token").Return("my-super-secret-auth-token").AnyTimes() fakeConfig.EXPECT().GetString("web.influxdb.token").Return("my-super-secret-auth-token").AnyTimes()
@ -405,17 +444,27 @@ func TestSendTestNotificationRoute_ShoutrrrFailure(t *testing.T) {
ae := web.AppEngine{ ae := web.AppEngine{
Config: fakeConfig, Config: fakeConfig,
} }
router := ae.Setup(logrus.New())
//test
wr := httptest.NewRecorder()
req, _ := http.NewRequest("POST", suite.Basepath+"/api/health/notify", strings.NewReader("{}"))
router.ServeHTTP(wr, req)
//assert
require.Equal(suite.T(), 500, wr.Code)
} }
func TestGetDevicesSummaryRoute_Nvme(t *testing.T) { func (suite *ServerTestSuite) TestGetDevicesSummaryRoute_Nvme() {
//setup //setup
parentPath, _ := ioutil.TempDir("", "") parentPath, _ := ioutil.TempDir("", "")
defer os.RemoveAll(parentPath) defer os.RemoveAll(parentPath)
mockCtrl := gomock.NewController(t) mockCtrl := gomock.NewController(suite.T())
defer mockCtrl.Finish() defer mockCtrl.Finish()
fakeConfig := mock_config.NewMockInterface(mockCtrl) fakeConfig := mock_config.NewMockInterface(mockCtrl)
fakeConfig.EXPECT().GetString("web.database.location").AnyTimes().Return(path.Join(parentPath, "scrutiny_test.db")) fakeConfig.EXPECT().GetString("web.database.location").AnyTimes().Return(path.Join(parentPath, "scrutiny_test.db"))
fakeConfig.EXPECT().GetString("web.src.frontend.path").AnyTimes().Return(parentPath) fakeConfig.EXPECT().GetString("web.src.frontend.path").AnyTimes().Return(parentPath)
fakeConfig.EXPECT().GetString("web.listen.basepath").Return(suite.Basepath).AnyTimes()
fakeConfig.EXPECT().GetString("web.influxdb.port").Return("8086").AnyTimes() fakeConfig.EXPECT().GetString("web.influxdb.port").Return("8086").AnyTimes()
fakeConfig.EXPECT().IsSet("web.influxdb.token").Return(true).AnyTimes() fakeConfig.EXPECT().IsSet("web.influxdb.token").Return(true).AnyTimes()
fakeConfig.EXPECT().GetString("web.influxdb.token").Return("my-super-secret-auth-token").AnyTimes() fakeConfig.EXPECT().GetString("web.influxdb.token").Return("my-super-secret-auth-token").AnyTimes()
@ -435,30 +484,30 @@ func TestGetDevicesSummaryRoute_Nvme(t *testing.T) {
} }
router := ae.Setup(logrus.New()) router := ae.Setup(logrus.New())
devicesfile, err := os.Open("testdata/register-devices-req-2.json") devicesfile, err := os.Open("testdata/register-devices-req-2.json")
require.NoError(t, err) require.NoError(suite.T(), err)
metricsfile := helperReadSmartDataFileFixTimestamp(t, "../models/testdata/smart-nvme2.json") metricsfile := helperReadSmartDataFileFixTimestamp(suite.T(), "../models/testdata/smart-nvme2.json")
//test //test
wr := httptest.NewRecorder() wr := httptest.NewRecorder()
req, _ := http.NewRequest("POST", "/api/devices/register", devicesfile) req, _ := http.NewRequest("POST", suite.Basepath+"/api/devices/register", devicesfile)
router.ServeHTTP(wr, req) router.ServeHTTP(wr, req)
require.Equal(t, 200, wr.Code) require.Equal(suite.T(), 200, wr.Code)
mr := httptest.NewRecorder() mr := httptest.NewRecorder()
req, _ = http.NewRequest("POST", "/api/device/a4c8e8ed-11a0-4c97-9bba-306440f1b944/smart", metricsfile) req, _ = http.NewRequest("POST", suite.Basepath+"/api/device/a4c8e8ed-11a0-4c97-9bba-306440f1b944/smart", metricsfile)
router.ServeHTTP(mr, req) router.ServeHTTP(mr, req)
require.Equal(t, 200, mr.Code) require.Equal(suite.T(), 200, mr.Code)
sr := httptest.NewRecorder() sr := httptest.NewRecorder()
req, _ = http.NewRequest("GET", "/api/summary", nil) req, _ = http.NewRequest("GET", suite.Basepath+"/api/summary", nil)
router.ServeHTTP(sr, req) router.ServeHTTP(sr, req)
require.Equal(t, 200, sr.Code) require.Equal(suite.T(), 200, sr.Code)
var deviceSummary models.DeviceSummaryWrapper var deviceSummary models.DeviceSummaryWrapper
err = json.Unmarshal(sr.Body.Bytes(), &deviceSummary) err = json.Unmarshal(sr.Body.Bytes(), &deviceSummary)
require.NoError(t, err) require.NoError(suite.T(), err)
//assert //assert
require.Equal(t, "a4c8e8ed-11a0-4c97-9bba-306440f1b944", deviceSummary.Data.Summary["a4c8e8ed-11a0-4c97-9bba-306440f1b944"].Device.WWN) require.Equal(suite.T(), "a4c8e8ed-11a0-4c97-9bba-306440f1b944", deviceSummary.Data.Summary["a4c8e8ed-11a0-4c97-9bba-306440f1b944"].Device.WWN)
require.Equal(t, pkg.DeviceStatusFailedScrutiny, deviceSummary.Data.Summary["a4c8e8ed-11a0-4c97-9bba-306440f1b944"].Device.DeviceStatus) require.Equal(suite.T(), pkg.DeviceStatusFailedScrutiny, deviceSummary.Data.Summary["a4c8e8ed-11a0-4c97-9bba-306440f1b944"].Device.DeviceStatus)
} }

Loading…
Cancel
Save