mirror of https://github.com/statping/statping
more tests
parent
701fac0298
commit
cead240508
|
@ -2,6 +2,7 @@
|
|||
- Fixed postgres timestamp grouping
|
||||
- Added postman (newman) API testing
|
||||
- Added Viper and Cobra config/env parsing package
|
||||
- Added more golang tests
|
||||
|
||||
# 0.90.27 (04-15-2020)
|
||||
- Fixed postgres database table creation process
|
||||
|
|
46
cmd/cli.go
46
cmd/cli.go
|
@ -7,9 +7,13 @@ import (
|
|||
"github.com/pkg/errors"
|
||||
"github.com/statping/statping/handlers"
|
||||
"github.com/statping/statping/source"
|
||||
"github.com/statping/statping/types/checkins"
|
||||
"github.com/statping/statping/types/configs"
|
||||
"github.com/statping/statping/types/core"
|
||||
"github.com/statping/statping/types/groups"
|
||||
"github.com/statping/statping/types/messages"
|
||||
"github.com/statping/statping/types/services"
|
||||
"github.com/statping/statping/types/users"
|
||||
"github.com/statping/statping/utils"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
@ -53,7 +57,7 @@ func exportCli(args []string) error {
|
|||
if _, err := services.SelectAllServices(false); err != nil {
|
||||
return err
|
||||
}
|
||||
if data, err = handlers.ExportSettings(); err != nil {
|
||||
if data, err = ExportSettings(); err != nil {
|
||||
return fmt.Errorf("could not export settings: %v", err.Error())
|
||||
}
|
||||
if err = utils.SaveFile(filename, data); err != nil {
|
||||
|
@ -99,7 +103,7 @@ func importCli(args []string) error {
|
|||
if data, err = ioutil.ReadFile(filename); err != nil {
|
||||
return err
|
||||
}
|
||||
var exportData handlers.ExportData
|
||||
var exportData ExportData
|
||||
if err = json.Unmarshal(data, &exportData); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -385,3 +389,41 @@ type gitUploader struct {
|
|||
Type string `json:"type"`
|
||||
SiteAdmin bool `json:"site_admin"`
|
||||
}
|
||||
|
||||
// ExportChartsJs renders the charts for the index page
|
||||
|
||||
type ExportData struct {
|
||||
Core *core.Core `json:"core"`
|
||||
Services []services.Service `json:"services"`
|
||||
Messages []*messages.Message `json:"messages"`
|
||||
Checkins []*checkins.Checkin `json:"checkins"`
|
||||
Users []*users.User `json:"users"`
|
||||
Groups []*groups.Group `json:"groups"`
|
||||
Notifiers []core.AllNotifiers `json:"notifiers"`
|
||||
}
|
||||
|
||||
// ExportSettings will export a JSON file containing all of the settings below:
|
||||
// - Core
|
||||
// - Notifiers
|
||||
// - Checkins
|
||||
// - Users
|
||||
// - Services
|
||||
// - Groups
|
||||
// - Messages
|
||||
func ExportSettings() ([]byte, error) {
|
||||
c, err := core.Select()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data := ExportData{
|
||||
Core: c,
|
||||
//Notifiers: notifications.All(),
|
||||
Checkins: checkins.All(),
|
||||
Users: users.All(),
|
||||
Services: services.AllInOrder(),
|
||||
Groups: groups.All(),
|
||||
Messages: messages.All(),
|
||||
}
|
||||
export, err := json.Marshal(data)
|
||||
return export, err
|
||||
}
|
||||
|
|
|
@ -131,12 +131,6 @@ func start() {
|
|||
exit(err)
|
||||
}
|
||||
|
||||
//log.Infoln("Migrating Notifiers...")
|
||||
//if err := notifier.Migrate(); err != nil {
|
||||
// exit(errors.Wrap(err, "error migrating notifiers"))
|
||||
//}
|
||||
//log.Infoln("Notifiers Migrated")
|
||||
|
||||
if err := mainProcess(); err != nil {
|
||||
exit(err)
|
||||
}
|
||||
|
|
|
@ -34,13 +34,6 @@ func init() {
|
|||
core.New("test")
|
||||
}
|
||||
|
||||
//func TestResetDatabase(t *testing.T) {
|
||||
// err := core.TmpRecords("handlers.db")
|
||||
// t.Log(err)
|
||||
// require.Nil(t, err)
|
||||
// require.NotNil(t, core.CoreApp)
|
||||
//}
|
||||
|
||||
func TestFailedHTTPServer(t *testing.T) {
|
||||
err := RunHTTPServer("missinghost", 0)
|
||||
assert.Error(t, err)
|
||||
|
@ -113,6 +106,7 @@ func TestSetupRoutes(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestMainApiRoutes(t *testing.T) {
|
||||
date := utils.Now().Format("2006-01-02")
|
||||
tests := []HTTPTest{
|
||||
{
|
||||
Name: "Statping Details",
|
||||
|
@ -135,6 +129,15 @@ func TestMainApiRoutes(t *testing.T) {
|
|||
BeforeTest: SetTestENV,
|
||||
SecureRoute: true,
|
||||
},
|
||||
{
|
||||
Name: "Statping View Cache",
|
||||
URL: "/api/cache",
|
||||
Method: "GET",
|
||||
ExpectedStatus: 200,
|
||||
BeforeTest: SetTestENV,
|
||||
SecureRoute: true,
|
||||
ResponseLen: 0,
|
||||
},
|
||||
{
|
||||
Name: "Statping Clear Cache",
|
||||
URL: "/api/clear_cache",
|
||||
|
@ -172,18 +175,40 @@ func TestMainApiRoutes(t *testing.T) {
|
|||
Method: "GET",
|
||||
ExpectedStatus: 404,
|
||||
},
|
||||
//{
|
||||
// Name: "Prometheus Export Metrics",
|
||||
// URL: "/metrics",
|
||||
// Method: "GET",
|
||||
// BeforeTest: SetTestENV,
|
||||
// ExpectedStatus: 200,
|
||||
// ExpectedContains: []string{
|
||||
// `Statping Totals`,
|
||||
// `total_failures`,
|
||||
// `Golang Metrics`,
|
||||
// },
|
||||
//},
|
||||
{
|
||||
Name: "Health Check endpoint",
|
||||
URL: "/health",
|
||||
Method: "GET",
|
||||
ExpectedStatus: 200,
|
||||
ExpectedContains: []string{`"online":true`, `"setup":true`},
|
||||
},
|
||||
{
|
||||
Name: "Logs endpoint",
|
||||
URL: "/api/logs",
|
||||
Method: "GET",
|
||||
ExpectedStatus: 200,
|
||||
GreaterThan: 50,
|
||||
ExpectedContains: []string{date},
|
||||
},
|
||||
{
|
||||
Name: "Logs Last Line endpoint",
|
||||
URL: "/api/logs/last",
|
||||
Method: "GET",
|
||||
ExpectedStatus: 200,
|
||||
ExpectedContains: []string{date},
|
||||
},
|
||||
{
|
||||
Name: "Prometheus Export Metrics",
|
||||
URL: "/metrics",
|
||||
Method: "GET",
|
||||
BeforeTest: SetTestENV,
|
||||
ExpectedStatus: 200,
|
||||
ExpectedContains: []string{
|
||||
`Statping Totals`,
|
||||
`total_failures`,
|
||||
`Golang Metrics`,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, v := range tests {
|
||||
|
@ -197,6 +222,8 @@ func TestMainApiRoutes(t *testing.T) {
|
|||
|
||||
type HttpFuncTest func(*testing.T) error
|
||||
|
||||
type ResponseFunc func(*testing.T, []byte) error
|
||||
|
||||
// HTTPTest contains all the parameters for a HTTP Unit Test
|
||||
type HTTPTest struct {
|
||||
Name string
|
||||
|
@ -211,8 +238,11 @@ type HTTPTest struct {
|
|||
FuncTest HttpFuncTest
|
||||
BeforeTest HttpFuncTest
|
||||
AfterTest HttpFuncTest
|
||||
ResponseFunc ResponseFunc
|
||||
ResponseLen int
|
||||
GreaterThan int
|
||||
SecureRoute bool
|
||||
Skip bool
|
||||
}
|
||||
|
||||
func logTest(t *testing.T, err error) error {
|
||||
|
@ -228,6 +258,9 @@ func logTest(t *testing.T, err error) error {
|
|||
|
||||
// RunHTTPTest accepts a HTTPTest type to execute the HTTP request
|
||||
func RunHTTPTest(test HTTPTest, t *testing.T) (string, *testing.T, error) {
|
||||
if test.Skip {
|
||||
t.SkipNow()
|
||||
}
|
||||
if test.BeforeTest != nil {
|
||||
if err := test.BeforeTest(t); err != nil {
|
||||
return "", t, logTest(t, err)
|
||||
|
@ -271,21 +304,24 @@ func RunHTTPTest(test HTTPTest, t *testing.T) (string, *testing.T, error) {
|
|||
err := test.FuncTest(t)
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
if test.ResponseFunc != nil {
|
||||
err := test.ResponseFunc(t, body)
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
if test.ResponseLen != 0 {
|
||||
var respArray []interface{}
|
||||
err := json.Unmarshal(body, &respArray)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, test.ResponseLen, len(respArray))
|
||||
}
|
||||
//if test.SecureRoute {
|
||||
// UnsetTestENV()
|
||||
// rec, err := Request(test)
|
||||
// if err != nil {
|
||||
// return "", t, logTest(t, err)
|
||||
// }
|
||||
// defer rec.Result().Body.Close()
|
||||
// assert.Equal(t, http.StatusUnauthorized, rec.Result().StatusCode)
|
||||
//}
|
||||
|
||||
if test.GreaterThan != 0 {
|
||||
var respArray []interface{}
|
||||
err := json.Unmarshal(body, &respArray)
|
||||
assert.Nil(t, err)
|
||||
assert.GreaterOrEqual(t, len(respArray), test.GreaterThan)
|
||||
}
|
||||
|
||||
if test.AfterTest != nil {
|
||||
if err := test.AfterTest(t); err != nil {
|
||||
|
@ -325,3 +361,7 @@ func StopServices(t *testing.T) error {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
Success = `"status":"success"`
|
||||
)
|
||||
|
|
|
@ -1,34 +1,79 @@
|
|||
package handlers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/statping/statping/types/checkins"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestApiCheckinRoutes(t *testing.T) {
|
||||
var apiToken string
|
||||
tests := []HTTPTest{
|
||||
{
|
||||
Name: "Statping Create Checkins",
|
||||
URL: "/api/checkins",
|
||||
Method: "POST",
|
||||
ExpectedStatus: 200,
|
||||
BeforeTest: SetTestENV,
|
||||
SecureRoute: true,
|
||||
ExpectedContains: []string{Success},
|
||||
Body: `{
|
||||
"name": "Example Checkin",
|
||||
"service_id": 1,
|
||||
"checkin_interval": 300,
|
||||
"grace_period": 60
|
||||
}`,
|
||||
},
|
||||
{
|
||||
Name: "Statping Checkins",
|
||||
URL: "/api/checkins",
|
||||
Method: "GET",
|
||||
ExpectedStatus: 200,
|
||||
ResponseLen: 3,
|
||||
BeforeTest: SetTestENV,
|
||||
SecureRoute: true,
|
||||
}, {
|
||||
Name: "Statping Create Checkin",
|
||||
URL: "/api/checkins",
|
||||
Method: "POST",
|
||||
Body: `{
|
||||
"service_id": 2,
|
||||
"name": "Server Checkin",
|
||||
"interval": 900,
|
||||
"grace": 60
|
||||
}`,
|
||||
ResponseFunc: func(t *testing.T, resp []byte) error {
|
||||
var checkin []*checkins.Checkin
|
||||
if err := json.Unmarshal(resp, &checkin); err != nil {
|
||||
return err
|
||||
}
|
||||
require.Len(t, checkin, 3)
|
||||
last := checkin[len(checkin)-1]
|
||||
apiToken = last.ApiKey
|
||||
require.NotEmpty(t, apiToken)
|
||||
return nil
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "Statping View Checkin",
|
||||
URL: "/api/checkins/" + apiToken,
|
||||
Method: "GET",
|
||||
ExpectedStatus: 200,
|
||||
ExpectedContains: []string{`"status":"success","type":"checkin","method":"create"`},
|
||||
ExpectedContains: []string{Success, `"type":"checkin","method":"create"`},
|
||||
BeforeTest: SetTestENV,
|
||||
SecureRoute: true,
|
||||
}}
|
||||
Skip: true,
|
||||
},
|
||||
{
|
||||
Name: "Statping Trigger Checkin",
|
||||
URL: "/checkin/" + apiToken,
|
||||
Method: "GET",
|
||||
ExpectedStatus: 200,
|
||||
ExpectedContains: []string{Success, `"type":"checkin","method":"create"`},
|
||||
SecureRoute: true,
|
||||
BeforeTest: SetTestENV,
|
||||
Skip: true,
|
||||
},
|
||||
{
|
||||
Name: "Statping Delete Checkin",
|
||||
URL: "/api/checkins/" + apiToken,
|
||||
Method: "DELETE",
|
||||
ExpectedContains: []string{Success, `"type":"checkin","method":"create"`},
|
||||
BeforeTest: SetTestENV,
|
||||
Skip: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, v := range tests {
|
||||
t.Run(v.Name, func(t *testing.T) {
|
||||
|
|
|
@ -17,15 +17,6 @@ func logoutHandler(w http.ResponseWriter, r *http.Request) {
|
|||
http.Redirect(w, r, basePath, http.StatusSeeOther)
|
||||
}
|
||||
|
||||
func helpHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if !IsUser(r) {
|
||||
http.Redirect(w, r, basePath, http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
help := source.HelpMarkdown()
|
||||
ExecuteResponse(w, r, "help.gohtml", help, nil)
|
||||
}
|
||||
|
||||
func logsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
utils.LockLines.Lock()
|
||||
logs := make([]string, 0)
|
||||
|
|
|
@ -1,49 +0,0 @@
|
|||
package handlers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/statping/statping/types/checkins"
|
||||
"github.com/statping/statping/types/core"
|
||||
"github.com/statping/statping/types/groups"
|
||||
"github.com/statping/statping/types/messages"
|
||||
"github.com/statping/statping/types/services"
|
||||
"github.com/statping/statping/types/users"
|
||||
)
|
||||
|
||||
// ExportChartsJs renders the charts for the index page
|
||||
|
||||
type ExportData struct {
|
||||
Core *core.Core `json:"core"`
|
||||
Services []services.Service `json:"services"`
|
||||
Messages []*messages.Message `json:"messages"`
|
||||
Checkins []*checkins.Checkin `json:"checkins"`
|
||||
Users []*users.User `json:"users"`
|
||||
Groups []*groups.Group `json:"groups"`
|
||||
Notifiers []core.AllNotifiers `json:"notifiers"`
|
||||
}
|
||||
|
||||
// ExportSettings will export a JSON file containing all of the settings below:
|
||||
// - Core
|
||||
// - Notifiers
|
||||
// - Checkins
|
||||
// - Users
|
||||
// - Services
|
||||
// - Groups
|
||||
// - Messages
|
||||
func ExportSettings() ([]byte, error) {
|
||||
c, err := core.Select()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data := ExportData{
|
||||
Core: c,
|
||||
//Notifiers: notifications.All(),
|
||||
Checkins: checkins.All(),
|
||||
Users: users.All(),
|
||||
Services: services.AllInOrder(),
|
||||
Groups: groups.All(),
|
||||
Messages: messages.All(),
|
||||
}
|
||||
export, err := json.Marshal(data)
|
||||
return export, err
|
||||
}
|
|
@ -4,6 +4,7 @@ import (
|
|||
"encoding/json"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/statping/statping/types/incidents"
|
||||
"github.com/statping/statping/types/services"
|
||||
"github.com/statping/statping/utils"
|
||||
"net/http"
|
||||
)
|
||||
|
@ -45,13 +46,20 @@ func apiCreateIncidentUpdateHandler(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
func apiCreateIncidentHandler(w http.ResponseWriter, r *http.Request) {
|
||||
var incident *incidents.Incident
|
||||
decoder := json.NewDecoder(r.Body)
|
||||
err := decoder.Decode(&incident)
|
||||
vars := mux.Vars(r)
|
||||
service, err := services.Find(utils.ToInt(vars["id"]))
|
||||
if err != nil {
|
||||
sendErrorJson(err, w, r)
|
||||
return
|
||||
}
|
||||
|
||||
var incident *incidents.Incident
|
||||
decoder := json.NewDecoder(r.Body)
|
||||
if err := decoder.Decode(&incident); err != nil {
|
||||
sendErrorJson(err, w, r)
|
||||
return
|
||||
}
|
||||
incident.ServiceId = service.Id
|
||||
err = incident.Create()
|
||||
if err != nil {
|
||||
sendErrorJson(err, w, r)
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
package handlers
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestIncidentsAPIRoutes(t *testing.T) {
|
||||
tests := []HTTPTest{
|
||||
{
|
||||
Name: "Statping Create Incident",
|
||||
URL: "/api/services/1/incidents",
|
||||
Method: "POST",
|
||||
ExpectedStatus: 200,
|
||||
BeforeTest: SetTestENV,
|
||||
AfterTest: UnsetTestENV,
|
||||
Body: `{
|
||||
"title": "New Incident",
|
||||
"description": "This is a test for incidents"
|
||||
}`,
|
||||
ExpectedContains: []string{Success},
|
||||
},
|
||||
{
|
||||
Name: "Statping Service 1 Incidents",
|
||||
URL: "/api/services/1/incidents",
|
||||
Method: "GET",
|
||||
ExpectedStatus: 200,
|
||||
ResponseLen: 1,
|
||||
BeforeTest: SetTestENV,
|
||||
AfterTest: UnsetTestENV,
|
||||
ExpectedContains: []string{`"title":"New Incident"`},
|
||||
},
|
||||
{
|
||||
Name: "Statping Update Incident",
|
||||
URL: "/api/incidents/1",
|
||||
Body: `{
|
||||
"title": "Updated Incident",
|
||||
"description": "This is an updated incidents"
|
||||
}`,
|
||||
Method: "POST",
|
||||
ExpectedStatus: 200,
|
||||
BeforeTest: SetTestENV,
|
||||
ExpectedContains: []string{Success},
|
||||
},
|
||||
{
|
||||
Name: "Statping View Incident Updates",
|
||||
URL: "/api/incidents/1/updates",
|
||||
Method: "GET",
|
||||
ExpectedStatus: 200,
|
||||
ResponseLen: 3,
|
||||
BeforeTest: SetTestENV,
|
||||
ExpectedContains: []string{`"type":"investigating"`},
|
||||
},
|
||||
{
|
||||
Name: "Statping Create Incident Update",
|
||||
URL: "/api/incidents/1/updates",
|
||||
Method: "POST",
|
||||
Body: `{
|
||||
"message": "Test message here",
|
||||
"type": "Update"
|
||||
}`,
|
||||
ExpectedStatus: 200,
|
||||
BeforeTest: SetTestENV,
|
||||
ExpectedContains: []string{Success},
|
||||
},
|
||||
{
|
||||
Name: "Statping Delete Incident Update",
|
||||
URL: "/api/incidents/1/updates/1",
|
||||
Method: "DELETE",
|
||||
ExpectedStatus: 200,
|
||||
BeforeTest: SetTestENV,
|
||||
ExpectedContains: []string{Success},
|
||||
},
|
||||
{
|
||||
Name: "Statping Delete Incident",
|
||||
URL: "/api/incidents/1",
|
||||
Method: "DELETE",
|
||||
ExpectedStatus: 200,
|
||||
BeforeTest: SetTestENV,
|
||||
ExpectedContains: []string{Success},
|
||||
},
|
||||
}
|
||||
|
||||
for _, v := range tests {
|
||||
t.Run(v.Name, func(t *testing.T) {
|
||||
_, t, err := RunHTTPTest(v, t)
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
}
|
||||
}
|
|
@ -162,3 +162,13 @@ func cached(duration, contentType string, handler func(w http.ResponseWriter, r
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
func DecodeJSON(r *http.Request, obj interface{}) error {
|
||||
decoder := json.NewDecoder(r.Body)
|
||||
err := decoder.Decode(&obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer r.Body.Close()
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -60,10 +60,6 @@ func prometheusHandler(w http.ResponseWriter, r *http.Request) {
|
|||
PrometheusKeyValue("total_services", len(services.Services()))
|
||||
PrometheusKeyValue("seconds_online", secondsOnline)
|
||||
|
||||
if secondsOnline < 5 {
|
||||
return
|
||||
}
|
||||
|
||||
for _, ser := range services.AllInOrder() {
|
||||
online := 1
|
||||
if !ser.Online {
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
package handlers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/statping/statping/utils"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func DecodeJSON(r *http.Request, obj interface{}) error {
|
||||
decoder := json.NewDecoder(r.Body)
|
||||
err := decoder.Decode(&obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetID(r *http.Request) (int64, error) {
|
||||
vars := mux.Vars(r)
|
||||
if vars["id"] == "" {
|
||||
return 0, errors.New("no id specified in request")
|
||||
}
|
||||
return utils.ToInt(vars["id"]), nil
|
||||
}
|
|
@ -112,7 +112,6 @@ func Router() *mux.Router {
|
|||
api.Handle("/api/services/{id}/failure_data", cached("30s", "application/json", apiServiceFailureDataHandler)).Methods("GET")
|
||||
api.Handle("/api/services/{id}/ping_data", cached("30s", "application/json", apiServicePingDataHandler)).Methods("GET")
|
||||
api.Handle("/api/services/{id}/uptime_data", http.HandlerFunc(apiServiceTimeDataHandler)).Methods("GET")
|
||||
//api.Handle("/api/services/{id}/heatmap", cached("30s", "application/json", apiServiceHeatmapHandler)).Methods("GET")
|
||||
|
||||
// API INCIDENTS Routes
|
||||
api.Handle("/api/services/{id}/incidents", http.HandlerFunc(apiServiceIncidentsHandler)).Methods("GET")
|
||||
|
@ -162,8 +161,8 @@ func Router() *mux.Router {
|
|||
r.Handle("/health", http.HandlerFunc(healthCheckHandler))
|
||||
r.Handle("/oauth/{provider}", http.HandlerFunc(oauthHandler))
|
||||
r.Handle("/.well-known/", http.StripPrefix("/.well-known/", http.FileServer(http.Dir(dir+"/.well-known"))))
|
||||
|
||||
r.NotFoundHandler = http.HandlerFunc(error404Handler)
|
||||
r.Handle("/", http.HandlerFunc(indexHandler))
|
||||
return r
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package handlers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/statping/statping/types"
|
||||
|
@ -9,12 +10,13 @@ import (
|
|||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestApiServiceRoutes(t *testing.T) {
|
||||
|
||||
since := utils.Now().Add(-30 * types.Day)
|
||||
startEndQuery := fmt.Sprintf("?start=%d&end=%d", since.Unix(), utils.Now().Unix())
|
||||
end := utils.Now().Add(-30 * time.Minute)
|
||||
startEndQuery := fmt.Sprintf("?start=%d&end=%d", since.Unix(), end.Unix()+15)
|
||||
|
||||
tests := []HTTPTest{
|
||||
{
|
||||
|
@ -75,9 +77,23 @@ func TestApiServiceRoutes(t *testing.T) {
|
|||
},
|
||||
{
|
||||
Name: "Statping Service Failures",
|
||||
URL: "/api/services/1/failures",
|
||||
URL: "/api/services/1/failures" + startEndQuery,
|
||||
Method: "GET",
|
||||
ResponseLen: 126,
|
||||
GreaterThan: 120,
|
||||
ExpectedStatus: 200,
|
||||
},
|
||||
{
|
||||
Name: "Statping Service 1 Hits",
|
||||
URL: "/api/services/1/hits" + startEndQuery,
|
||||
Method: "GET",
|
||||
GreaterThan: 8580,
|
||||
ExpectedStatus: 200,
|
||||
},
|
||||
{
|
||||
Name: "Statping Service 2 Hits",
|
||||
URL: "/api/services/2/hits" + startEndQuery,
|
||||
Method: "GET",
|
||||
GreaterThan: 8580,
|
||||
ExpectedStatus: 200,
|
||||
},
|
||||
{
|
||||
|
@ -88,55 +104,73 @@ func TestApiServiceRoutes(t *testing.T) {
|
|||
ExpectedStatus: 200,
|
||||
},
|
||||
{
|
||||
Name: "Statping Service 1 Data",
|
||||
Name: "Statping Service 1 Hits Data",
|
||||
URL: "/api/services/1/hits_data" + startEndQuery,
|
||||
Method: "GET",
|
||||
ResponseLen: 73,
|
||||
GreaterThan: 70,
|
||||
ExpectedStatus: 200,
|
||||
},
|
||||
{
|
||||
Name: "Statping Service 1 Ping Data",
|
||||
URL: "/api/services/1/ping_data" + startEndQuery,
|
||||
Method: "GET",
|
||||
ResponseLen: 73,
|
||||
ExpectedStatus: 200,
|
||||
GreaterThan: 70,
|
||||
},
|
||||
{
|
||||
Name: "Statping Service 1 Failure Data - 24 Hour",
|
||||
URL: "/api/services/1/failure_data" + startEndQuery + "&group=24h",
|
||||
Method: "GET",
|
||||
ExpectedStatus: 200,
|
||||
GreaterThan: 4,
|
||||
},
|
||||
{
|
||||
Name: "Statping Service 1 Failure Data - 12 Hour",
|
||||
URL: "/api/services/1/failure_data" + startEndQuery + "&group=12h",
|
||||
Method: "GET",
|
||||
ExpectedStatus: 200,
|
||||
GreaterThan: 7,
|
||||
},
|
||||
{
|
||||
Name: "Statping Service 1 Failure Data - 1 Hour",
|
||||
URL: "/api/services/1/failure_data" + startEndQuery + "&group=1h",
|
||||
Method: "GET",
|
||||
ExpectedStatus: 200,
|
||||
GreaterThan: 70,
|
||||
},
|
||||
{
|
||||
Name: "Statping Service 1 Failure Data - 15 Minute",
|
||||
URL: "/api/services/1/failure_data" + startEndQuery + "&group=15m",
|
||||
Method: "GET",
|
||||
ResponseLen: 125,
|
||||
GreaterThan: 120,
|
||||
ExpectedStatus: 200,
|
||||
},
|
||||
{
|
||||
Name: "Statping Service 1 Hits",
|
||||
URL: "/api/services/1/hits_data" + startEndQuery,
|
||||
Method: "GET",
|
||||
ResponseLen: 73,
|
||||
GreaterThan: 70,
|
||||
ExpectedStatus: 200,
|
||||
},
|
||||
{
|
||||
Name: "Statping Service 1 Uptime",
|
||||
URL: "/api/services/1/uptime_data" + startEndQuery,
|
||||
Method: "GET",
|
||||
ExpectedStatus: 200,
|
||||
ResponseFunc: func(t *testing.T, resp []byte) error {
|
||||
var uptime *services.UptimeSeries
|
||||
if err := json.Unmarshal(resp, &uptime); err != nil {
|
||||
return err
|
||||
}
|
||||
assert.GreaterOrEqual(t, uptime.Uptime, int64(259100000))
|
||||
return nil
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "Statping Service 1 Failure Data",
|
||||
URL: "/api/services/1/failure_data" + startEndQuery,
|
||||
Method: "GET",
|
||||
GreaterThan: 70,
|
||||
ExpectedStatus: 200,
|
||||
},
|
||||
{
|
||||
|
@ -169,7 +203,7 @@ func TestApiServiceRoutes(t *testing.T) {
|
|||
"order_id": 0
|
||||
}`,
|
||||
ExpectedStatus: 200,
|
||||
ExpectedContains: []string{`"status":"success","type":"service","method":"create"`, `"public":false`, `"group_id":1`},
|
||||
ExpectedContains: []string{Success, `"type":"service","method":"create"`, `"public":false`, `"group_id":1`},
|
||||
FuncTest: func(t *testing.T) error {
|
||||
count := len(services.Services())
|
||||
if count != 7 {
|
||||
|
@ -198,7 +232,7 @@ func TestApiServiceRoutes(t *testing.T) {
|
|||
"order_id": 0
|
||||
}`,
|
||||
ExpectedStatus: 200,
|
||||
ExpectedContains: []string{`"status":"success"`, `"name":"Updated New Service"`, `"method":"update"`},
|
||||
ExpectedContains: []string{Success, `"name":"Updated New Service"`, `"method":"update"`},
|
||||
FuncTest: func(t *testing.T) error {
|
||||
item, err := services.Find(1)
|
||||
require.Nil(t, err)
|
||||
|
@ -214,7 +248,7 @@ func TestApiServiceRoutes(t *testing.T) {
|
|||
URL: "/api/services/1/failures",
|
||||
Method: "DELETE",
|
||||
ExpectedStatus: 200,
|
||||
ExpectedContains: []string{`"status":"success"`, `"method":"delete_failures"`},
|
||||
ExpectedContains: []string{Success, `"method":"delete_failures"`},
|
||||
FuncTest: func(t *testing.T) error {
|
||||
item, err := services.Find(1)
|
||||
require.Nil(t, err)
|
||||
|
@ -231,7 +265,7 @@ func TestApiServiceRoutes(t *testing.T) {
|
|||
URL: "/api/services/1",
|
||||
Method: "DELETE",
|
||||
ExpectedStatus: 200,
|
||||
ExpectedContains: []string{`"status":"success"`, `"method":"delete"`},
|
||||
ExpectedContains: []string{Success, `"method":"delete"`},
|
||||
FuncTest: func(t *testing.T) error {
|
||||
count := len(services.Services())
|
||||
if count != 6 {
|
||||
|
|
|
@ -15,7 +15,7 @@ func (c *Checkin) Expected() time.Duration {
|
|||
}
|
||||
|
||||
func (c *Checkin) Period() time.Duration {
|
||||
duration, _ := time.ParseDuration(fmt.Sprintf("%vs", c.Interval))
|
||||
duration, _ := time.ParseDuration(fmt.Sprintf("%ds", c.Interval))
|
||||
return duration
|
||||
}
|
||||
|
||||
|
|
|
@ -38,18 +38,17 @@ CheckinLoop:
|
|||
c.Failing = false
|
||||
break CheckinLoop
|
||||
case <-time.After(reCheck):
|
||||
log.Infoln(fmt.Sprintf("Checkin %v is expected at %v, checking every %v", c.Name, utils.FormatDuration(c.Expected()), utils.FormatDuration(c.Period())))
|
||||
log.Infoln(fmt.Sprintf("Checkin '%s' expects a request every %v", c.Name, utils.FormatDuration(c.Period())))
|
||||
if c.Expected() <= 0 {
|
||||
issue := fmt.Sprintf("Checkin %v is failing, no request since %v", c.Name, lastHit.CreatedAt)
|
||||
log.Errorln(issue)
|
||||
issue := fmt.Sprintf("Checkin '%s' is failing, no request since %v", c.Name, lastHit.CreatedAt)
|
||||
//log.Errorln(issue)
|
||||
|
||||
fail := &failures.Failure{
|
||||
Issue: issue,
|
||||
Method: "checkin",
|
||||
Service: c.ServiceId,
|
||||
Checkin: c.Id,
|
||||
PingTime: c.Expected().Milliseconds(),
|
||||
CreatedAt: time.Time{},
|
||||
Issue: issue,
|
||||
Method: "checkin",
|
||||
Service: c.ServiceId,
|
||||
Checkin: c.Id,
|
||||
PingTime: c.Expected().Milliseconds(),
|
||||
}
|
||||
|
||||
c.CreateFailure(fail)
|
||||
|
|
|
@ -31,7 +31,7 @@ func Samples() error {
|
|||
}
|
||||
|
||||
func SamplesChkHits() error {
|
||||
checkTime := time.Now().UTC().Add(-24 * time.Hour)
|
||||
checkTime := utils.Now().Add(-3 * time.Minute)
|
||||
|
||||
for i := int64(1); i <= 2; i++ {
|
||||
checkHit := &CheckinHit{
|
||||
|
@ -44,7 +44,7 @@ func SamplesChkHits() error {
|
|||
return err
|
||||
}
|
||||
|
||||
checkTime = checkTime.Add(10 * time.Minute)
|
||||
checkTime = checkTime.Add(1 * time.Minute)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -36,10 +36,12 @@ func (d *DbConfig) ConnectionString() string {
|
|||
return conn
|
||||
}
|
||||
|
||||
func loadConfigEnvs() (*DbConfig, error) {
|
||||
log.Infof("Loading configs from environment variables")
|
||||
func LoadConfigFile(directory string) (*DbConfig, error) {
|
||||
p := utils.Params
|
||||
config := &DbConfig{
|
||||
log.Infof("Attempting to read config file at: %s/config.yml ", directory)
|
||||
utils.Params.SetConfigFile(directory + "/config.yml")
|
||||
|
||||
configs := &DbConfig{
|
||||
DbConn: p.GetString("DB_CONN"),
|
||||
DbHost: p.GetString("DB_HOST"),
|
||||
DbUser: p.GetString("DB_USER"),
|
||||
|
@ -55,5 +57,7 @@ func loadConfigEnvs() (*DbConfig, error) {
|
|||
Location: utils.Directory,
|
||||
SqlFile: p.GetString("SQL_FILE"),
|
||||
}
|
||||
return config, nil
|
||||
|
||||
log.WithFields(utils.ToFields(configs)).Debugln("read config file: " + directory + "/config.yml")
|
||||
return configs, nil
|
||||
}
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
package configs
|
||||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
"github.com/statping/statping/types/core"
|
||||
"github.com/statping/statping/utils"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
func LoadConfigFile(directory string) (*DbConfig, error) {
|
||||
var configs *DbConfig
|
||||
log.Infof("Attempting to read config file at: %s/config.yml ", directory)
|
||||
file, err := utils.OpenFile(directory + "/config.yml")
|
||||
if err != nil {
|
||||
core.App.Setup = false
|
||||
return nil, errors.Wrapf(err, "config.yml file not found at %s/config.yml - starting in setup mode", directory)
|
||||
}
|
||||
err = yaml.Unmarshal([]byte(file), &configs)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "yaml file not formatted correctly")
|
||||
}
|
||||
log.WithFields(utils.ToFields(configs)).Debugln("read config file: " + directory + "/config.yml")
|
||||
|
||||
return configs, nil
|
||||
}
|
|
@ -10,18 +10,19 @@ func LoadConfigForm(r *http.Request) (*DbConfig, error) {
|
|||
if err := r.ParseForm(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dbHost := r.PostForm.Get("db_host")
|
||||
dbUser := r.PostForm.Get("db_user")
|
||||
dbPass := r.PostForm.Get("db_password")
|
||||
dbDatabase := r.PostForm.Get("db_database")
|
||||
dbConn := r.PostForm.Get("db_connection")
|
||||
dbPort := utils.ToInt(r.PostForm.Get("db_port"))
|
||||
project := r.PostForm.Get("project")
|
||||
username := r.PostForm.Get("username")
|
||||
password := r.PostForm.Get("password")
|
||||
description := r.PostForm.Get("description")
|
||||
domain := r.PostForm.Get("domain")
|
||||
email := r.PostForm.Get("email")
|
||||
g := r.PostForm.Get
|
||||
dbHost := g("db_host")
|
||||
dbUser := g("db_user")
|
||||
dbPass := g("db_password")
|
||||
dbDatabase := g("db_database")
|
||||
dbConn := g("db_connection")
|
||||
dbPort := utils.ToInt(g("db_port"))
|
||||
project := g("project")
|
||||
username := g("username")
|
||||
password := g("password")
|
||||
description := g("description")
|
||||
domain := g("domain")
|
||||
email := g("email")
|
||||
|
||||
if project == "" || username == "" || password == "" {
|
||||
err := errors.New("Missing required elements on setup form")
|
||||
|
|
|
@ -30,14 +30,6 @@ func LoadConfigs() (*DbConfig, error) {
|
|||
return nil, errors.Errorf("Directory %s is not writable!", utils.Directory)
|
||||
}
|
||||
|
||||
if utils.Params.GetString("DB_CONN") != "" {
|
||||
configs, err := loadConfigEnvs()
|
||||
if err != nil {
|
||||
return LoadConfigFile(utils.Directory)
|
||||
}
|
||||
return configs, nil
|
||||
}
|
||||
|
||||
return LoadConfigFile(utils.Directory)
|
||||
}
|
||||
|
||||
|
|
|
@ -9,17 +9,3 @@ func (d *DbConfig) Save(directory string) error {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// defaultPort accepts a database type and returns its default port
|
||||
func defaultPort(db string) int {
|
||||
switch db {
|
||||
case "mysql":
|
||||
return 3306
|
||||
case "postgres":
|
||||
return 5432
|
||||
case "mssql":
|
||||
return 1433
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,12 +39,16 @@ func Select() (*Core, error) {
|
|||
}
|
||||
|
||||
func (c *Core) Create() error {
|
||||
secret := utils.Params.GetString("API_SECRET")
|
||||
if secret == "" {
|
||||
secret = utils.RandomString(32)
|
||||
}
|
||||
newCore := &Core{
|
||||
Name: c.Name,
|
||||
Description: c.Description,
|
||||
ConfigFile: utils.Directory + "/config.yml",
|
||||
ApiKey: utils.Params.GetString("API_KEY"),
|
||||
ApiSecret: utils.Params.GetString("API_SECRET"),
|
||||
ApiKey: utils.RandomString(32),
|
||||
ApiSecret: secret,
|
||||
Version: App.Version,
|
||||
Domain: c.Domain,
|
||||
MigrationId: utils.Now().Unix(),
|
||||
|
|
|
@ -48,8 +48,6 @@ func setDefaults() {
|
|||
Params.SetDefault("MAX_OPEN_CONN", 25)
|
||||
Params.SetDefault("MAX_IDLE_CONN", 25)
|
||||
Params.SetDefault("MAX_LIFE_CONN", 5*time.Minute)
|
||||
Params.SetDefault("API_KEY", RandomString(32))
|
||||
Params.SetDefault("API_SECRET", RandomString(32))
|
||||
Params.SetDefault("SAMPLE_DATA", true)
|
||||
Params.SetDefault("USE_CDN", false)
|
||||
Params.SetDefault("ALLOW_REPORTS", false)
|
||||
|
|
|
@ -189,3 +189,18 @@ func TestHttpRequest(t *testing.T) {
|
|||
assert.Equal(t, []byte("OK"), body)
|
||||
assert.Equal(t, resp.StatusCode, 200)
|
||||
}
|
||||
|
||||
func TestConfigLoad(t *testing.T) {
|
||||
os.Setenv("DB_CONN", "sqlite")
|
||||
InitCLI()
|
||||
setDefaults()
|
||||
|
||||
s := Params.GetString
|
||||
b := Params.GetBool
|
||||
|
||||
assert.Equal(t, "sqlite", s("DB_CONN"))
|
||||
assert.Equal(t, Directory, s("STATPING_DIR"))
|
||||
assert.True(t, b("SAMPLE_DATA"))
|
||||
assert.False(t, b("DISABLE_LOGS"))
|
||||
assert.False(t, b("ALLOW_REPORTS"))
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue