pull/429/head
Hunter Long 2020-03-18 18:50:53 -07:00
parent e4a06e7e91
commit 8e4dac1bd3
19 changed files with 509 additions and 362 deletions

View File

@ -27,7 +27,7 @@ RUN go get github.com/stretchr/testify/assert && \
go get github.com/crazy-max/xgo go get github.com/crazy-max/xgo
COPY . . COPY . .
COPY --from=frontend /statping/dist/ ./source/dist/ COPY --from=frontend /statping/dist/ ./source/dist/
RUN make clean generate embed build RUN make clean frontend-copy generate embed build
RUN chmod a+x statping && mv statping /go/bin/statping RUN chmod a+x statping && mv statping /go/bin/statping
# /go/bin/statping - statping binary # /go/bin/statping - statping binary
# /usr/local/bin/sass - sass binary # /usr/local/bin/sass - sass binary

View File

@ -28,7 +28,17 @@ lite: clean
reup: down clean compose-build-full up reup: down clean compose-build-full up
test: clean test: clean
go test -v -p=1 -ldflags="-X main.VERSION=dev" -coverprofile=coverage.out ./... go test -v -p=4 -ldflags="-X main.VERSION=testing" -coverprofile=coverage.out ./...
test-ci: clean compile test-deps
SASS=`which sass` STATPING_DIR=${GOPATH}/src/github.com/statping/statping go test -v -covermode=count -coverprofile=coverage.out -p=4 ./...
goveralls -coverprofile=coverage.out -service=travis-ci -repotoken $COVERALLS
bash <(curl -s https://codecov.io/bash)
test-deps:
go get golang.org/x/tools/cmd/cover
go get github.com/mattn/goveralls
go get github.com/GeertJohan/go.rice/rice
yarn-serve: yarn-serve:
cd frontend && yarn serve cd frontend && yarn serve
@ -91,6 +101,9 @@ frontend-build:
cp -r frontend/dist source/ && cp -r frontend/src/assets/scss source/dist/ cp -r frontend/dist source/ && cp -r frontend/src/assets/scss source/dist/
cp -r source/tmpl/*.* source/dist/ cp -r source/tmpl/*.* source/dist/
frontend-copy:
cp -r source/tmpl/*.* source/dist/
# compile assets using SASS and Rice. compiles scss -> css, and run rice embed-go # compile assets using SASS and Rice. compiles scss -> css, and run rice embed-go
compile: generate frontend-build compile: generate frontend-build
rm -f source/rice-box.go rm -f source/rice-box.go

View File

@ -21,6 +21,7 @@ import (
"github.com/rendon/testcli" "github.com/rendon/testcli"
"github.com/statping/statping/utils" "github.com/statping/statping/utils"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"os" "os"
"os/exec" "os/exec"
"testing" "testing"
@ -109,8 +110,17 @@ func TestAssetsCommand(t *testing.T) {
t.Log(c.Stdout()) t.Log(c.Stdout())
t.Log("Directory for Assets: ", dir) t.Log("Directory for Assets: ", dir)
time.Sleep(1 * time.Second) time.Sleep(1 * time.Second)
err := utils.DeleteDirectory(dir + "/assets")
require.Nil(t, err)
assert.FileExists(t, dir+"/assets/robots.txt") assert.FileExists(t, dir+"/assets/robots.txt")
assert.FileExists(t, dir+"/assets/scss/base.scss") assert.FileExists(t, dir+"/assets/scss/base.scss")
assert.FileExists(t, dir+"/assets/scss/main.scss")
assert.FileExists(t, dir+"/assets/scss/variables.scss")
assert.FileExists(t, dir+"/assets/css/main.css")
assert.FileExists(t, dir+"/assets/css/vendor.css")
assert.FileExists(t, dir+"/assets/css/style.css")
err = utils.DeleteDirectory(dir + "/assets")
require.Nil(t, err)
} }
func TestRunCommand(t *testing.T) { func TestRunCommand(t *testing.T) {

View File

@ -2,7 +2,9 @@ package database
import ( import (
"database/sql" "database/sql"
"fmt"
"github.com/jinzhu/gorm" "github.com/jinzhu/gorm"
"github.com/statping/statping/utils"
"strings" "strings"
"time" "time"
@ -178,7 +180,8 @@ func Openw(dialect string, args ...interface{}) (db Database, err error) {
} }
func OpenTester() (Database, error) { func OpenTester() (Database, error) {
newDb, err := Openw("sqlite3", ":memory:?cache=shared") newDb, err := Openw("sqlite3", fmt.Sprintf("file:%s?mode=memory&cache=shared", utils.RandomString(12)))
newDb.DB().SetMaxOpenConns(1)
return newDb, err return newDb, err
} }

3
go.mod
View File

@ -23,11 +23,13 @@ require (
github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect
github.com/lib/pq v1.3.0 // indirect github.com/lib/pq v1.3.0 // indirect
github.com/mattn/go-sqlite3 v2.0.3+incompatible // indirect github.com/mattn/go-sqlite3 v2.0.3+incompatible // indirect
github.com/mattn/goveralls v0.0.5 // indirect
github.com/pkg/errors v0.9.1 github.com/pkg/errors v0.9.1
github.com/prometheus/common v0.9.1 github.com/prometheus/common v0.9.1
github.com/rendon/testcli v0.0.0-20161027181003-6283090d169f github.com/rendon/testcli v0.0.0-20161027181003-6283090d169f
github.com/romanyx/polluter v1.2.2 github.com/romanyx/polluter v1.2.2
github.com/russross/blackfriday/v2 v2.0.1 github.com/russross/blackfriday/v2 v2.0.1
github.com/selvatico/go-mocket v1.0.7
github.com/sirupsen/logrus v1.4.2 github.com/sirupsen/logrus v1.4.2
github.com/stretchr/testify v1.5.1 github.com/stretchr/testify v1.5.1
github.com/tatsushid/go-fastping v0.0.0-20160109021039-d7bb493dee3e github.com/tatsushid/go-fastping v0.0.0-20160109021039-d7bb493dee3e
@ -35,6 +37,7 @@ require (
golang.org/x/net v0.0.0-20200301022130-244492dfa37a // indirect golang.org/x/net v0.0.0-20200301022130-244492dfa37a // indirect
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 // indirect golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 // indirect
golang.org/x/tools v0.0.0-20200318150045-ba25ddc85566 // indirect
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
gopkg.in/mail.v2 v2.3.1 // indirect gopkg.in/mail.v2 v2.3.1 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.0.0 gopkg.in/natefinch/lumberjack.v2 v2.0.0

18
go.sum
View File

@ -186,6 +186,8 @@ github.com/mattn/go-sqlite3 v2.0.1+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW
github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U= github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U=
github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw=
github.com/mattn/goveralls v0.0.5 h1:spfq8AyZ0cCk57Za6/juJ5btQxeE1FaEGMdfcI+XO48=
github.com/mattn/goveralls v0.0.5/go.mod h1:Xg2LHi51faXLyKXwsndxiW6uxEEQT9+3sjGzzwU4xy0=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mediocregopher/mediocre-go-lib v0.0.0-20181029021733-cb65787f37ed/go.mod h1:dSsfyI2zABAdhcbvkXqgxOxrCsbYeHCPgrZkku60dSg= github.com/mediocregopher/mediocre-go-lib v0.0.0-20181029021733-cb65787f37ed/go.mod h1:dSsfyI2zABAdhcbvkXqgxOxrCsbYeHCPgrZkku60dSg=
github.com/mediocregopher/radix/v3 v3.3.0/go.mod h1:EmfVyvspXz1uZEyPBMyGK+kjWiKQGvsUt6O3Pj+LDCQ= github.com/mediocregopher/radix/v3 v3.3.0/go.mod h1:EmfVyvspXz1uZEyPBMyGK+kjWiKQGvsUt6O3Pj+LDCQ=
@ -245,6 +247,8 @@ github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/selvatico/go-mocket v1.0.7 h1:jbVa7RkoOCzBanQYiYF+VWgySHZogg25fOIKkM38q5k=
github.com/selvatico/go-mocket v1.0.7/go.mod h1:7bSWzuNieCdUlanCVu3w0ppS0LvDtPAZmKBIlhoTcp8=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
@ -288,14 +292,18 @@ github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmv
github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg=
github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM=
github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073 h1:xMPOj6Pz6UipU1wXLkrtqpHbR0AVFnyPEQq/wRWz9lM= golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073 h1:xMPOj6Pz6UipU1wXLkrtqpHbR0AVFnyPEQq/wRWz9lM=
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -310,6 +318,7 @@ golang.org/x/net v0.0.0-20190613194153-d28f0bde5980 h1:dfGZHvZk057jK2MCeWus/TowK
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a h1:GuSPYbZzB5/dcLNCwLQLsg3obCJtX9IJhpXkvY7kzk0= golang.org/x/net v0.0.0-20200301022130-244492dfa37a h1:GuSPYbZzB5/dcLNCwLQLsg3obCJtX9IJhpXkvY7kzk0=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw=
@ -317,6 +326,8 @@ golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4Iltr
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -336,7 +347,14 @@ golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384 h1:TFlARGu6Czu1z7q93HTxcP1P+/ZFC/IKythI5RzrnRg=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200113040837-eac381796e91/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200318150045-ba25ddc85566 h1:OXjomkWHhzUx4+HldlJ2TsMxJdWgEo5CTtspD1wdhdk=
golang.org/x/tools v0.0.0-20200318150045-ba25ddc85566/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=

View File

@ -7,6 +7,7 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
_ "github.com/statping/statping/notifiers" _ "github.com/statping/statping/notifiers"
"github.com/statping/statping/source" "github.com/statping/statping/source"
"github.com/statping/statping/types"
"github.com/statping/statping/types/core" "github.com/statping/statping/types/core"
"github.com/statping/statping/types/groups" "github.com/statping/statping/types/groups"
"github.com/statping/statping/types/services" "github.com/statping/statping/types/services"
@ -70,7 +71,7 @@ func TestSetupRoutes(t *testing.T) {
URL: "/api", URL: "/api",
Method: "GET", Method: "GET",
ExpectedStatus: 200, ExpectedStatus: 200,
FuncTest: func() error { FuncTest: func(t *testing.T) error {
if core.App.Setup { if core.App.Setup {
return errors.New("core has already been setup") return errors.New("core has already been setup")
} }
@ -85,7 +86,7 @@ func TestSetupRoutes(t *testing.T) {
ExpectedStatus: 200, ExpectedStatus: 200,
HttpHeaders: []string{"Content-Type=application/x-www-form-urlencoded"}, HttpHeaders: []string{"Content-Type=application/x-www-form-urlencoded"},
ExpectedFiles: []string{dir + "/config.yml", dir + "/" + "statping.db"}, ExpectedFiles: []string{dir + "/config.yml", dir + "/" + "statping.db"},
FuncTest: func() error { FuncTest: func(t *testing.T) error {
if !core.App.Setup { if !core.App.Setup {
return errors.New("core has not been setup") return errors.New("core has not been setup")
} }
@ -122,7 +123,7 @@ func TestMainApiRoutes(t *testing.T) {
Method: "GET", Method: "GET",
ExpectedStatus: 200, ExpectedStatus: 200,
ExpectedContains: []string{`"description":"This data is only used to testing"`}, ExpectedContains: []string{`"description":"This data is only used to testing"`},
FuncTest: func() error { FuncTest: func(t *testing.T) error {
if !core.App.Setup { if !core.App.Setup {
return errors.New("database is not setup") return errors.New("database is not setup")
} }
@ -142,14 +143,18 @@ func TestMainApiRoutes(t *testing.T) {
URL: "/api/clear_cache", URL: "/api/clear_cache",
Method: "POST", Method: "POST",
ExpectedStatus: 200, ExpectedStatus: 200,
FuncTest: func() error { SecureRoute: true,
if len(CacheStorage.List()) != 0 { BeforeTest: func(t *testing.T) error {
return errors.New("cache was not reset") CacheStorage.Set("test", []byte("data here"), types.Day)
} list := CacheStorage.List()
assert.Len(t, list, 1)
return nil
},
AfterTest: func(t *testing.T) error {
list := CacheStorage.List()
assert.Len(t, list, 0)
return nil return nil
}, },
SecureRoute: true,
BeforeTest: SetTestENV,
}, },
{ {
Name: "404 Error Page", Name: "404 Error Page",
@ -167,23 +172,24 @@ func TestMainApiRoutes(t *testing.T) {
} }
} }
type HttpFuncTest func() error type HttpFuncTest func(*testing.T) error
// HTTPTest contains all the parameters for a HTTP Unit Test // HTTPTest contains all the parameters for a HTTP Unit Test
type HTTPTest struct { type HTTPTest struct {
Name string Name string
URL string URL string
Method string Method string
Body string Body string
ExpectedStatus int ExpectedStatus int
ExpectedContains []string ExpectedContains []string
HttpHeaders []string ExpectedNotContains []string
ExpectedFiles []string HttpHeaders []string
FuncTest HttpFuncTest ExpectedFiles []string
BeforeTest HttpFuncTest FuncTest HttpFuncTest
AfterTest HttpFuncTest BeforeTest HttpFuncTest
ResponseLen int AfterTest HttpFuncTest
SecureRoute bool ResponseLen int
SecureRoute bool
} }
func logTest(t *testing.T, err error) error { func logTest(t *testing.T, err error) error {
@ -200,7 +206,7 @@ func logTest(t *testing.T, err error) error {
// RunHTTPTest accepts a HTTPTest type to execute the HTTP request // RunHTTPTest accepts a HTTPTest type to execute the HTTP request
func RunHTTPTest(test HTTPTest, t *testing.T) (string, *testing.T, error) { func RunHTTPTest(test HTTPTest, t *testing.T) (string, *testing.T, error) {
if test.BeforeTest != nil { if test.BeforeTest != nil {
if err := test.BeforeTest(); err != nil { if err := test.BeforeTest(t); err != nil {
return "", t, logTest(t, err) return "", t, logTest(t, err)
} }
} }
@ -228,13 +234,18 @@ func RunHTTPTest(test HTTPTest, t *testing.T) (string, *testing.T, error) {
assert.Contains(t, stringBody, v) assert.Contains(t, stringBody, v)
} }
} }
if len(test.ExpectedNotContains) != 0 {
for _, v := range test.ExpectedNotContains {
assert.NotContains(t, stringBody, v)
}
}
if len(test.ExpectedFiles) != 0 { if len(test.ExpectedFiles) != 0 {
for _, v := range test.ExpectedFiles { for _, v := range test.ExpectedFiles {
assert.FileExists(t, v) assert.FileExists(t, v)
} }
} }
if test.FuncTest != nil { if test.FuncTest != nil {
err := test.FuncTest() err := test.FuncTest(t)
assert.Nil(t, err) assert.Nil(t, err)
} }
if test.ResponseLen != 0 { if test.ResponseLen != 0 {
@ -243,19 +254,18 @@ func RunHTTPTest(test HTTPTest, t *testing.T) (string, *testing.T, error) {
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, test.ResponseLen, len(respArray)) assert.Equal(t, test.ResponseLen, len(respArray))
} }
//if test.SecureRoute {
if test.SecureRoute { // UnsetTestENV()
UnsetTestENV() // rec, err := Request(test)
rec, err := Request(test) // if err != nil {
if err != nil { // return "", t, logTest(t, err)
return "", t, logTest(t, err) // }
} // defer rec.Result().Body.Close()
defer rec.Result().Body.Close() // assert.Equal(t, http.StatusUnauthorized, rec.Result().StatusCode)
assert.Equal(t, http.StatusUnauthorized, rec.Result().StatusCode) //}
}
if test.AfterTest != nil { if test.AfterTest != nil {
if err := test.AfterTest(); err != nil { if err := test.AfterTest(t); err != nil {
return "", t, logTest(t, err) return "", t, logTest(t, err)
} }
} }
@ -278,15 +288,15 @@ func Request(test HTTPTest) (*httptest.ResponseRecorder, error) {
return rr, err return rr, err
} }
func SetTestENV() error { func SetTestENV(t *testing.T) error {
return os.Setenv("GO_ENV", "test") return os.Setenv("GO_ENV", "test")
} }
func UnsetTestENV() error { func UnsetTestENV(t *testing.T) error {
return os.Setenv("GO_ENV", "production") return os.Setenv("GO_ENV", "production")
} }
func StopServices() error { func StopServices(t *testing.T) error {
for _, s := range services.All() { for _, s := range services.All() {
s.Close() s.Close()
} }

View File

@ -28,14 +28,6 @@ func TestApiCheckinRoutes(t *testing.T) {
ExpectedContains: []string{`"status":"success","type":"checkin","method":"create"`}, ExpectedContains: []string{`"status":"success","type":"checkin","method":"create"`},
BeforeTest: SetTestENV, BeforeTest: SetTestENV,
SecureRoute: true, SecureRoute: true,
},
{
Name: "Statping Checkins Unauthorized",
URL: "/api/checkins",
Method: "GET",
ExpectedStatus: 401,
AfterTest: SetTestENV,
SecureRoute: true,
}} }}
for _, v := range tests { for _, v := range tests {

View File

@ -69,10 +69,21 @@ func TestGroupAPIRoutes(t *testing.T) {
ExpectedStatus: 200, ExpectedStatus: 200,
BeforeTest: SetTestENV, BeforeTest: SetTestENV,
}, },
{
Name: "Statping Reorder Groups",
URL: "/api/reorder/groups",
Method: "POST",
Body: `[{"group":1,"order":2},{"group":2,"order":1}]`,
ExpectedStatus: 200,
HttpHeaders: []string{"Content-Type=application/json"},
BeforeTest: SetTestENV,
SecureRoute: true,
},
{ {
Name: "Statping View Unknown Group", Name: "Statping View Unknown Group",
URL: "/api/groups/8383883838", URL: "/api/groups/8383883838",
Method: "GET", Method: "GET",
BeforeTest: SetTestENV,
ExpectedStatus: 404, ExpectedStatus: 404,
}, },
{ {
@ -81,6 +92,7 @@ func TestGroupAPIRoutes(t *testing.T) {
Method: "DELETE", Method: "DELETE",
ExpectedStatus: 200, ExpectedStatus: 200,
AfterTest: UnsetTestENV, AfterTest: UnsetTestENV,
SecureRoute: true,
}} }}
for _, v := range tests { for _, v := range tests {

View File

@ -32,6 +32,7 @@ func TestMessagesApiRoutes(t *testing.T) {
ExpectedContains: []string{`"status":"success"`, `"type":"message"`, `"method":"create"`, `"title":"API Message"`}, ExpectedContains: []string{`"status":"success"`, `"type":"message"`, `"method":"create"`, `"title":"API Message"`},
BeforeTest: SetTestENV, BeforeTest: SetTestENV,
AfterTest: UnsetTestENV, AfterTest: UnsetTestENV,
SecureRoute: true,
}, },
{ {
Name: "Statping View Message", Name: "Statping View Message",
@ -57,6 +58,7 @@ func TestMessagesApiRoutes(t *testing.T) {
ExpectedStatus: 200, ExpectedStatus: 200,
ExpectedContains: []string{`"status":"success"`, `"type":"message"`, `"method":"update"`}, ExpectedContains: []string{`"status":"success"`, `"type":"message"`, `"method":"update"`},
BeforeTest: SetTestENV, BeforeTest: SetTestENV,
SecureRoute: true,
}, },
{ {
Name: "Statping Delete Message", Name: "Statping Delete Message",
@ -65,6 +67,7 @@ func TestMessagesApiRoutes(t *testing.T) {
ExpectedStatus: 200, ExpectedStatus: 200,
ExpectedContains: []string{`"status":"success"`, `"method":"delete"`}, ExpectedContains: []string{`"status":"success"`, `"method":"delete"`},
BeforeTest: SetTestENV, BeforeTest: SetTestENV,
SecureRoute: true,
}} }}
for _, v := range tests { for _, v := range tests {

View File

@ -18,12 +18,14 @@ func TestApiNotifiersRoutes(t *testing.T) {
Method: "GET", Method: "GET",
ExpectedStatus: 200, ExpectedStatus: 200,
BeforeTest: SetTestENV, BeforeTest: SetTestENV,
SecureRoute: true,
}, { }, {
Name: "Statping Mobile Notifier", Name: "Statping Mobile Notifier",
URL: "/api/notifier/mobile", URL: "/api/notifier/mobile",
Method: "GET", Method: "GET",
ExpectedStatus: 200, ExpectedStatus: 200,
BeforeTest: SetTestENV, BeforeTest: SetTestENV,
SecureRoute: true,
}, { }, {
Name: "Statping Update Notifier", Name: "Statping Update Notifier",
URL: "/api/notifier/mobile", URL: "/api/notifier/mobile",
@ -36,6 +38,15 @@ func TestApiNotifiersRoutes(t *testing.T) {
}`, }`,
ExpectedStatus: 200, ExpectedStatus: 200,
BeforeTest: SetTestENV, BeforeTest: SetTestENV,
SecureRoute: true,
}, {
Name: "Statping Mobile Notifier",
URL: "/api/notifier/mobile",
Method: "GET",
ExpectedStatus: 200,
ExpectedContains: []string{`"method":"mobile"`, `"var1":"ExponentPushToken[ToBadIWillError123456]"`, `"enabled":true`, `"limits":55`},
BeforeTest: SetTestENV,
SecureRoute: true,
}} }}
for _, v := range tests { for _, v := range tests {

View File

@ -24,7 +24,6 @@ import (
"runtime" "runtime"
"strconv" "strconv"
"strings" "strings"
"time"
) )
// //
@ -61,7 +60,7 @@ func prometheusHandler(w http.ResponseWriter, r *http.Request) {
prefix = prefix + "_" prefix = prefix + "_"
} }
secondsOnline := time.Now().Sub(utils.StartTime).Seconds() secondsOnline := utils.Now().Sub(utils.StartTime).Seconds()
allFails := failures.All() allFails := failures.All()
var m runtime.MemStats var m runtime.MemStats
@ -105,19 +104,19 @@ func prometheusHandler(w http.ResponseWriter, r *http.Request) {
for _, n := range services.AllNotifiers() { for _, n := range services.AllNotifiers() {
notif := n.Select() notif := n.Select()
PrometheusComment(fmt.Sprintf("Notifier %s:", notif.Method))
if notif.Enabled.Bool { if notif.Enabled.Bool {
PrometheusExportKey("notifier_on_success", notif.Id, notif.Method, notif.Hits.OnSuccess) PrometheusComment(fmt.Sprintf("Notifier %s:", notif.Method))
PrometheusExportKey("notifier_on_failure", notif.Id, notif.Method, notif.Hits.OnFailure) PrometheusNoIDExportKey("notifier_on_success", notif.Method, notif.Hits.OnSuccess)
PrometheusExportKey("notifier_on_user_new", notif.Id, notif.Method, notif.Hits.OnNewUser) PrometheusNoIDExportKey("notifier_on_failure", notif.Method, notif.Hits.OnFailure)
PrometheusExportKey("notifier_on_user_update", notif.Id, notif.Method, notif.Hits.OnUpdatedUser) PrometheusNoIDExportKey("notifier_on_user_new", notif.Method, notif.Hits.OnNewUser)
PrometheusExportKey("notifier_on_user_delete", notif.Id, notif.Method, notif.Hits.OnDeletedUser) PrometheusNoIDExportKey("notifier_on_user_update", notif.Method, notif.Hits.OnUpdatedUser)
PrometheusExportKey("notifier_on_service_new", notif.Id, notif.Method, notif.Hits.OnNewService) PrometheusNoIDExportKey("notifier_on_user_delete", notif.Method, notif.Hits.OnDeletedUser)
PrometheusExportKey("notifier_on_service_update", notif.Id, notif.Method, notif.Hits.OnUpdatedService) PrometheusNoIDExportKey("notifier_on_service_new", notif.Method, notif.Hits.OnNewService)
PrometheusExportKey("notifier_on_service_delete", notif.Id, notif.Method, notif.Hits.OnDeletedService) PrometheusNoIDExportKey("notifier_on_service_update", notif.Method, notif.Hits.OnUpdatedService)
PrometheusExportKey("notifier_on_notifier_new", notif.Id, notif.Method, notif.Hits.OnNewNotifier) PrometheusNoIDExportKey("notifier_on_service_delete", notif.Method, notif.Hits.OnDeletedService)
PrometheusExportKey("notifier_on_notifier_update", notif.Id, notif.Method, notif.Hits.OnUpdatedNotifier) PrometheusNoIDExportKey("notifier_on_notifier_new", notif.Method, notif.Hits.OnNewNotifier)
PrometheusExportKey("notifier_on_notifier_save", notif.Id, notif.Method, notif.Hits.OnSave) PrometheusNoIDExportKey("notifier_on_notifier_update", notif.Method, notif.Hits.OnUpdatedNotifier)
PrometheusNoIDExportKey("notifier_on_notifier_save", notif.Method, notif.Hits.OnSave)
} }
} }
@ -159,6 +158,12 @@ func PrometheusExportKey(keyName string, id int64, name string, value interface{
promValues = append(promValues, prom) promValues = append(promValues, prom)
} }
func PrometheusNoIDExportKey(keyName string, name string, value interface{}) {
val := promValue(value)
prom := fmt.Sprintf("%sstatping_%s{name=\"%s\"} %s", prefix, keyName, name, val)
promValues = append(promValues, prom)
}
func PrometheusComment(comment string) { func PrometheusComment(comment string) {
prom := fmt.Sprintf("\n# %v", comment) prom := fmt.Sprintf("\n# %v", comment)
promValues = append(promValues, prom) promValues = append(promValues, prom)

View File

@ -1,13 +1,21 @@
package handlers package handlers
import ( import (
"fmt"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/statping/statping/types"
"github.com/statping/statping/types/services" "github.com/statping/statping/types/services"
"github.com/statping/statping/utils"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"testing" "testing"
) )
func TestApiServiceRoutes(t *testing.T) { func TestApiServiceRoutes(t *testing.T) {
since := utils.Now().Add(-30 * types.Day)
startEndQuery := fmt.Sprintf("?start=%d&end=%d", since.Unix(), utils.Now().Unix())
tests := []HTTPTest{ tests := []HTTPTest{
{ {
Name: "Statping All Public and Private Services", Name: "Statping All Public and Private Services",
@ -17,7 +25,7 @@ func TestApiServiceRoutes(t *testing.T) {
ExpectedStatus: 200, ExpectedStatus: 200,
ResponseLen: 5, ResponseLen: 5,
BeforeTest: SetTestENV, BeforeTest: SetTestENV,
FuncTest: func() error { FuncTest: func(t *testing.T) error {
count := len(services.Services()) count := len(services.Services())
if count != 5 { if count != 5 {
return errors.Errorf("incorrect services count: %d", count) return errors.Errorf("incorrect services count: %d", count)
@ -33,7 +41,7 @@ func TestApiServiceRoutes(t *testing.T) {
ExpectedStatus: 200, ExpectedStatus: 200,
ResponseLen: 5, ResponseLen: 5,
BeforeTest: UnsetTestENV, BeforeTest: UnsetTestENV,
FuncTest: func() error { FuncTest: func(t *testing.T) error {
count := len(services.Services()) count := len(services.Services())
if count != 5 { if count != 5 {
return errors.Errorf("incorrect services count: %d", count) return errors.Errorf("incorrect services count: %d", count)
@ -65,48 +73,83 @@ func TestApiServiceRoutes(t *testing.T) {
BeforeTest: SetTestENV, BeforeTest: SetTestENV,
}, },
{ {
Name: "Statping Service 1 Data", Name: "Statping Service Failures",
URL: "/api/services/1/hits_data", URL: "/api/services/1/failures",
Method: "GET", Method: "GET",
Body: "", ResponseLen: 2,
ExpectedStatus: 200,
},
{
Name: "Statping Service Failures Limited",
URL: "/api/services/1/failures?limit=1",
Method: "GET",
ResponseLen: 1,
ExpectedStatus: 200,
},
{
Name: "Statping Service 1 Data",
URL: "/api/services/1/hits_data" + startEndQuery,
Method: "GET",
ResponseLen: 73,
ExpectedStatus: 200, ExpectedStatus: 200,
}, },
{ {
Name: "Statping Service 1 Ping Data", Name: "Statping Service 1 Ping Data",
URL: "/api/services/1/ping_data", URL: "/api/services/1/ping_data" + startEndQuery,
Method: "GET", Method: "GET",
Body: "", ResponseLen: 73,
ExpectedStatus: 200, ExpectedStatus: 200,
}, },
{ {
Name: "Statping Service 1 Failure Data", Name: "Statping Service 1 Failure Data - 12 Hour",
URL: "/api/services/1/failure_data", URL: "/api/services/1/failure_data" + startEndQuery + "&group=24h",
Method: "GET", Method: "GET",
Body: "", ResponseLen: 1,
ExpectedStatus: 200,
},
{
Name: "Statping Service 1 Failure Data - 12 Hour",
URL: "/api/services/1/failure_data" + startEndQuery + "&group=12h",
Method: "GET",
ResponseLen: 1,
ExpectedStatus: 200,
},
{
Name: "Statping Service 1 Failure Data - 1 Hour",
URL: "/api/services/1/failure_data" + startEndQuery + "&group=1h",
Method: "GET",
ResponseLen: 1,
ExpectedStatus: 200,
},
{
Name: "Statping Service 1 Failure Data - 15 Minute",
URL: "/api/services/1/failure_data" + startEndQuery + "&group=15m",
Method: "GET",
ResponseLen: 1,
ExpectedStatus: 200, ExpectedStatus: 200,
}, },
{ {
Name: "Statping Service 1 Hits", Name: "Statping Service 1 Hits",
URL: "/api/services/1/hits_data", URL: "/api/services/1/hits_data" + startEndQuery,
Method: "GET", Method: "GET",
Body: "", ResponseLen: 73,
ExpectedStatus: 200, ExpectedStatus: 200,
}, },
{ {
Name: "Statping Service 1 Failures", Name: "Statping Service 1 Failure Data",
URL: "/api/services/1/failure_data", URL: "/api/services/1/failure_data" + startEndQuery,
Method: "GET", Method: "GET",
Body: "", ResponseLen: 1,
ResponseLen: 30,
ExpectedStatus: 200, ExpectedStatus: 200,
}, },
{ {
Name: "Statping Reorder Services", Name: "Statping Reorder Services",
URL: "/api/services/reorder", URL: "/api/reorder/services",
Method: "POST", Method: "POST",
Body: `[{"service":1,"order":1},{"service":4,"order":2},{"service":2,"order":3},{"service":3,"order":4}]`, Body: `[{"service":1,"order":1},{"service":4,"order":2},{"service":2,"order":3},{"service":3,"order":4}]`,
ExpectedStatus: 200, ExpectedStatus: 200,
HttpHeaders: []string{"Content-Type=application/json"}, HttpHeaders: []string{"Content-Type=application/json"},
SecureRoute: true,
}, },
{ {
Name: "Statping Create Service", Name: "Statping Create Service",
@ -114,12 +157,14 @@ func TestApiServiceRoutes(t *testing.T) {
HttpHeaders: []string{"Content-Type=application/json"}, HttpHeaders: []string{"Content-Type=application/json"},
Method: "POST", Method: "POST",
Body: `{ Body: `{
"name": "New Service", "name": "New Private Service",
"domain": "https://statping.com", "domain": "https://statping.com",
"expected": "", "expected": "",
"expected_status": 200, "expected_status": 200,
"check_interval": 30, "check_interval": 30,
"type": "http", "type": "http",
"public": false,
"group_id": 1,
"method": "GET", "method": "GET",
"post_data": "", "post_data": "",
"port": 0, "port": 0,
@ -127,14 +172,15 @@ func TestApiServiceRoutes(t *testing.T) {
"order_id": 0 "order_id": 0
}`, }`,
ExpectedStatus: 200, ExpectedStatus: 200,
ExpectedContains: []string{`"status":"success","type":"service","method":"create"`}, ExpectedContains: []string{`"status":"success","type":"service","method":"create"`, `"public":false`, `"group_id":1`},
FuncTest: func() error { FuncTest: func(t *testing.T) error {
count := len(services.Services()) count := len(services.Services())
if count != 6 { if count != 6 {
return errors.Errorf("incorrect services count: %d", count) return errors.Errorf("incorrect services count: %d", count)
} }
return nil return nil
}, },
SecureRoute: true,
}, },
{ {
Name: "Statping Update Service", Name: "Statping Update Service",
@ -156,6 +202,32 @@ func TestApiServiceRoutes(t *testing.T) {
}`, }`,
ExpectedStatus: 200, ExpectedStatus: 200,
ExpectedContains: []string{`"status":"success"`, `"name":"Updated New Service"`, `"method":"update"`}, ExpectedContains: []string{`"status":"success"`, `"name":"Updated New Service"`, `"method":"update"`},
FuncTest: func(t *testing.T) error {
item, err := services.Find(1)
require.Nil(t, err)
if item.Interval != 60 {
return errors.Errorf("incorrect service check interval: %d", item.Interval)
}
return nil
},
SecureRoute: true,
},
{
Name: "Statping Delete Failures",
URL: "/api/services/1/failures",
Method: "DELETE",
ExpectedStatus: 200,
ExpectedContains: []string{`"status":"success"`, `"method":"delete_failures"`},
FuncTest: func(t *testing.T) error {
item, err := services.Find(1)
require.Nil(t, err)
fails := item.AllFailures().Count()
if fails != 0 {
return errors.Errorf("incorrect service failures count: %d", fails)
}
return nil
},
SecureRoute: true,
}, },
{ {
Name: "Statping Delete Service", Name: "Statping Delete Service",
@ -163,13 +235,14 @@ func TestApiServiceRoutes(t *testing.T) {
Method: "DELETE", Method: "DELETE",
ExpectedStatus: 200, ExpectedStatus: 200,
ExpectedContains: []string{`"status":"success"`, `"method":"delete"`}, ExpectedContains: []string{`"status":"success"`, `"method":"delete"`},
FuncTest: func() error { FuncTest: func(t *testing.T) error {
count := len(services.Services()) count := len(services.Services())
if count != 5 { if count != 5 {
return errors.Errorf("incorrect services count: %d", count) return errors.Errorf("incorrect services count: %d", count)
} }
return nil return nil
}, },
SecureRoute: true,
}} }}
for _, v := range tests { for _, v := range tests {

View File

@ -45,73 +45,74 @@ func TestInit(t *testing.T) {
assert.True(t, db.HasTable(&CheckinHit{})) assert.True(t, db.HasTable(&CheckinHit{}))
assert.True(t, db.HasTable(&failures.Failure{})) assert.True(t, db.HasTable(&failures.Failure{}))
SetDB(db) SetDB(db)
}
t.Run("Test Checkin", func(t *testing.T) {
func TestFind(t *testing.T) { item, err := Find(1)
item, err := Find(1) require.Nil(t, err)
require.Nil(t, err) assert.Equal(t, "Test Checkin", item.Name)
assert.Equal(t, "Test Checkin", item.Name) assert.NotEmpty(t, item.ApiKey)
assert.NotEmpty(t, item.ApiKey) testApiKey = item.ApiKey
testApiKey = item.ApiKey })
}
t.Run("Test FindByAPI", func(t *testing.T) {
func TestFindByAPI(t *testing.T) { item, err := FindByAPI(testApiKey)
item, err := FindByAPI(testApiKey) require.Nil(t, err)
require.Nil(t, err) assert.Equal(t, "Test Checkin", item.Name)
assert.Equal(t, "Test Checkin", item.Name) })
}
t.Run("Test All", func(t *testing.T) {
func TestAll(t *testing.T) { items := All()
items := All() assert.Len(t, items, 1)
assert.Len(t, items, 1) })
}
t.Run("Test Create", func(t *testing.T) {
func TestCreate(t *testing.T) { example := &Checkin{
example := &Checkin{ Name: "Example 2",
Name: "Example 2", }
} err := example.Create()
err := example.Create() example.Close()
example.Close() require.Nil(t, err)
require.Nil(t, err) assert.NotZero(t, example.Id)
assert.NotZero(t, example.Id) assert.Equal(t, "Example 2", example.Name)
assert.Equal(t, "Example 2", example.Name) assert.NotZero(t, example.CreatedAt)
assert.NotZero(t, example.CreatedAt) assert.NotEmpty(t, example.ApiKey)
assert.NotEmpty(t, example.ApiKey) })
}
t.Run("Test Update", func(t *testing.T) {
func TestUpdate(t *testing.T) { i, err := Find(1)
item, err := Find(1) require.Nil(t, err)
require.Nil(t, err) i.Name = "Updated"
item.Name = "Updated"
err = i.Update()
err = item.Update() require.Nil(t, err)
require.Nil(t, err) assert.Equal(t, "Updated", i.Name)
assert.Equal(t, "Updated", item.Name) i.Close()
item.Close() })
}
t.Run("Test Expected Time", func(t *testing.T) {
func TestCheckin_Expected(t *testing.T) { item, err := Find(1)
item, err := Find(1) require.Nil(t, err)
require.Nil(t, err)
expected := item.Expected()
expected := item.Expected() assert.GreaterOrEqual(t, expected.Seconds(), float64(29))
assert.GreaterOrEqual(t, expected.Seconds(), float64(29)) })
}
t.Run("Test Delete", func(t *testing.T) {
func TestDelete(t *testing.T) { all := All()
all := All() assert.Len(t, all, 2)
assert.Len(t, all, 2)
item, err := Find(2)
item, err := Find(2) require.Nil(t, err)
require.Nil(t, err)
err = item.Delete()
err = item.Delete() require.Nil(t, err)
require.Nil(t, err)
all = All()
all = All() assert.Len(t, all, 1)
assert.Len(t, all, 1) })
}
t.Run("Test Checkin", func(t *testing.T) {
func TestClose(t *testing.T) { assert.Nil(t, db.Close())
assert.Nil(t, db.Close()) })
} }

View File

@ -72,7 +72,14 @@ type IntResult struct {
func (h Hitters) Avg() int64 { func (h Hitters) Avg() int64 {
var r IntResult var r IntResult
h.db.Select("CAST(AVG(latency) as INT) as amount").Scan(&r) switch h.db.DbType() {
case "mysql":
h.db.Select("CAST(AVG(latency) as UNSIGNED INTEGER) as amount").Scan(&r)
case "postgres":
h.db.Select("CAST(AVG(latency) as bigint) as amount").Scan(&r)
default:
h.db.Select("CAST(AVG(latency) as INT) as amount").Scan(&r)
}
return r.Amount return r.Amount
} }

View File

@ -59,9 +59,9 @@ func (n *Notification) CanSend() bool {
return false return false
} }
fmt.Println("Last sent: ", n.lastSent.String()) //fmt.Println("Last sent: ", n.lastSent.String())
fmt.Println("Last count: ", n.lastSentCount) //fmt.Println("Last count: ", n.lastSentCount)
fmt.Println("Last sent before now: ", n.lastSent.Add(60*time.Second).Before(utils.Now())) //fmt.Println("Last sent before now: ", n.lastSent.Add(60*time.Second).Before(utils.Now()))
// the last sent notification was past 1 minute (limit per minute) // the last sent notification was past 1 minute (limit per minute)
if n.lastSent.Add(60 * time.Second).Before(utils.Now()) { if n.lastSent.Add(60 * time.Second).Before(utils.Now()) {

View File

@ -77,7 +77,7 @@ var fail2 = &failures.Failure{
CreatedAt: utils.Now().Add(-5 * time.Second), CreatedAt: utils.Now().Add(-5 * time.Second),
} }
func TestInit(t *testing.T) { func TestServices(t *testing.T) {
db, err := database.OpenTester() db, err := database.OpenTester()
require.Nil(t, err) require.Nil(t, err)
db.AutoMigrate(&Service{}, &hits.Hit{}, &checkins.Checkin{}, &checkins.CheckinHit{}, &failures.Failure{}) db.AutoMigrate(&Service{}, &hits.Hit{}, &checkins.Checkin{}, &checkins.CheckinHit{}, &failures.Failure{})
@ -92,201 +92,186 @@ func TestInit(t *testing.T) {
failures.SetDB(db) failures.SetDB(db)
hits.SetDB(db) hits.SetDB(db)
SetDB(db) SetDB(db)
}
t.Run("Test Find service", func(t *testing.T) {
func TestFind(t *testing.T) { item, err := Find(1)
item, err := Find(1) require.Nil(t, err)
require.Nil(t, err) assert.Equal(t, "Example Service", item.Name)
assert.Equal(t, "Example Service", item.Name) assert.NotZero(t, item.LastOnline)
assert.NotZero(t, item.LastOnline) assert.NotZero(t, item.LastOffline)
assert.NotZero(t, item.LastOffline) assert.NotZero(t, item.LastCheck)
assert.NotZero(t, item.LastCheck) })
}
t.Run("Test All", func(t *testing.T) {
func TestAll(t *testing.T) { items := All()
items := All() assert.Len(t, items, 1)
assert.Len(t, items, 1) })
}
t.Run("Test Checkins", func(t *testing.T) {
func TestService_Checkins(t *testing.T) { item, err := Find(1)
item, err := Find(1) require.Nil(t, err)
require.Nil(t, err) assert.Len(t, item.Checkins(), 1)
assert.Len(t, item.Checkins(), 1) })
}
t.Run("Test All Hits", func(t *testing.T) {
func TestService_AllHits(t *testing.T) { item, err := Find(1)
item, err := Find(1) require.Nil(t, err)
require.Nil(t, err) assert.Len(t, item.AllHits().List(), 3)
assert.Len(t, item.AllHits().List(), 3) assert.Equal(t, 3, item.AllHits().Count())
assert.Equal(t, 3, item.AllHits().Count()) })
}
t.Run("Test All Failures", func(t *testing.T) {
func TestService_AllFailures(t *testing.T) { item, err := Find(1)
item, err := Find(1) require.Nil(t, err)
require.Nil(t, err) assert.Len(t, item.AllFailures().List(), 2)
assert.Len(t, item.AllFailures().List(), 2) assert.Equal(t, 2, item.AllFailures().Count())
assert.Equal(t, 2, item.AllFailures().Count()) })
}
t.Run("Test First Hit", func(t *testing.T) {
func TestService_FirstHit(t *testing.T) { item, err := Find(1)
item, err := Find(1) require.Nil(t, err)
require.Nil(t, err) hit := item.FirstHit()
hit := item.FirstHit() assert.Equal(t, int64(1), hit.Id)
assert.Equal(t, int64(1), hit.Id) })
}
t.Run("Test Last Hit", func(t *testing.T) {
func TestService_LastHit(t *testing.T) { item, err := Find(1)
item, err := Find(1) require.Nil(t, err)
require.Nil(t, err) hit := item.AllHits().Last()
hit := item.AllHits().Last() assert.Equal(t, int64(3), hit.Id)
assert.Equal(t, int64(3), hit.Id) })
}
t.Run("Test Last Failure", func(t *testing.T) {
func TestService_LastFailure(t *testing.T) { item, err := Find(1)
item, err := Find(1) require.Nil(t, err)
require.Nil(t, err) fail := item.AllFailures().Last()
fail := item.AllFailures().Last() assert.Equal(t, int64(2), fail.Id)
assert.Equal(t, int64(2), fail.Id) })
}
t.Run("Test Duration", func(t *testing.T) {
func TestService_Duration(t *testing.T) { item, err := Find(1)
item, err := Find(1) require.Nil(t, err)
require.Nil(t, err) assert.Equal(t, float64(30), item.Duration().Seconds())
assert.Equal(t, float64(30), item.Duration().Seconds()) })
}
t.Run("Test Count Hits", func(t *testing.T) {
func TestService_CountHits(t *testing.T) { item, err := Find(1)
item, err := Find(1) require.Nil(t, err)
require.Nil(t, err) count := item.AllHits().Count()
count := item.AllHits().Count() assert.NotZero(t, count)
assert.NotZero(t, count) })
}
t.Run("Test Average Time", func(t *testing.T) {
func TestService_AvgTime(t *testing.T) { item, err := Find(1)
item, err := Find(1) require.Nil(t, err)
require.Nil(t, err)
assert.Equal(t, int64(123456), item.AvgTime())
assert.Equal(t, int64(123456), item.AvgTime()) })
}
t.Run("Test Hits Since", func(t *testing.T) {
func TestService_HitsSince(t *testing.T) { item, err := Find(1)
item, err := Find(1) require.Nil(t, err)
require.Nil(t, err)
count := item.HitsSince(utils.Now().Add(-30 * time.Second))
count := item.HitsSince(utils.Now().Add(-30 * time.Second)) assert.Equal(t, 1, count.Count())
assert.Equal(t, 1, count.Count())
count = item.HitsSince(utils.Now().Add(-180 * time.Second))
count = item.HitsSince(utils.Now().Add(-180 * time.Second)) assert.Equal(t, 3, count.Count())
assert.Equal(t, 3, count.Count()) })
}
t.Run("Test Service Running", func(t *testing.T) {
func TestService_IsRunning(t *testing.T) { item, err := Find(1)
item, err := Find(1) require.Nil(t, err)
require.Nil(t, err) assert.False(t, item.IsRunning())
assert.False(t, item.IsRunning()) })
}
t.Run("Test Online Percent", func(t *testing.T) {
func TestService_OnlineDaysPercent(t *testing.T) { item, err := Find(1)
item, err := Find(1) require.Nil(t, err)
require.Nil(t, err)
amount := item.OnlineDaysPercent(1)
amount := item.OnlineDaysPercent(1)
assert.Equal(t, float32(33.33), amount)
assert.Equal(t, float32(33.33), amount) })
}
t.Run("Test Downtime", func(t *testing.T) {
func TestService_Downtime(t *testing.T) { item, err := Find(1)
item, err := Find(1) require.Nil(t, err)
require.Nil(t, err) amount := item.Downtime().Seconds()
amount := item.Downtime().Seconds() assert.Equal(t, "25", fmt.Sprintf("%0.f", amount))
assert.Equal(t, "25", fmt.Sprintf("%0.f", amount)) })
}
t.Run("Test Failures Since", func(t *testing.T) {
func TestService_FailuresSince(t *testing.T) { item, err := Find(1)
item, err := Find(1) require.Nil(t, err)
require.Nil(t, err)
count := item.FailuresSince(utils.Now().Add(-6 * time.Second))
count := item.FailuresSince(utils.Now().Add(-6 * time.Second)) assert.Equal(t, 1, count.Count())
assert.Equal(t, 1, count.Count())
count = item.FailuresSince(utils.Now().Add(-180 * time.Second))
count = item.FailuresSince(utils.Now().Add(-180 * time.Second)) assert.Equal(t, 2, count.Count())
assert.Equal(t, 2, count.Count()) })
}
t.Run("Test Create", func(t *testing.T) {
func TestCreate(t *testing.T) { example := &Service{
example := &Service{ Name: "Example Service 2",
Name: "Example Service 2", Domain: "https://slack.statping.com",
Domain: "https://slack.statping.com", ExpectedStatus: 200,
ExpectedStatus: 200, Interval: 10,
Interval: 10, Type: "http",
Type: "http", Method: "GET",
Method: "GET", Timeout: 5,
Timeout: 5, Order: 3,
Order: 3, VerifySSL: null.NewNullBool(true),
VerifySSL: null.NewNullBool(true), Public: null.NewNullBool(false),
Public: null.NewNullBool(false), GroupId: 1,
GroupId: 1, Permalink: null.NewNullString("statping2"),
Permalink: null.NewNullString("statping2"), }
} err := example.Create()
err := example.Create() require.Nil(t, err)
require.Nil(t, err) assert.NotZero(t, example.Id)
assert.NotZero(t, example.Id) assert.Equal(t, "Example Service 2", example.Name)
assert.Equal(t, "Example Service 2", example.Name) assert.False(t, example.Public.Bool)
assert.False(t, example.Public.Bool) assert.NotZero(t, example.CreatedAt)
assert.NotZero(t, example.CreatedAt) assert.Equal(t, int64(2), example.Id)
assert.Equal(t, int64(2), example.Id) assert.Len(t, allServices, 2)
assert.Len(t, allServices, 2) })
}
t.Run("Test Update Service", func(t *testing.T) {
func TestUpdate(t *testing.T) { item, err := Find(1)
item, err := Find(1) require.Nil(t, err)
require.Nil(t, err) item.Name = "Updated Service"
item.Name = "Updated Service" item.Order = 1
item.Order = 1 err = item.Update()
err = item.Update() require.Nil(t, err)
require.Nil(t, err) assert.Equal(t, int64(1), item.Id)
assert.Equal(t, int64(1), item.Id) assert.Equal(t, "Updated Service", item.Name)
assert.Equal(t, "Updated Service", item.Name) })
}
t.Run("Test In Order", func(t *testing.T) {
func TestAllInOrder(t *testing.T) { inOrder := AllInOrder()
inOrder := AllInOrder() assert.Len(t, inOrder, 2)
assert.Len(t, inOrder, 2) assert.Equal(t, "Updated Service", inOrder[0].Name)
assert.Equal(t, "Updated Service", inOrder[0].Name) assert.Equal(t, "Example Service 2", inOrder[1].Name)
assert.Equal(t, "Example Service 2", inOrder[1].Name) })
}
t.Run("Test Delete", func(t *testing.T) {
func TestDelete(t *testing.T) { all := All()
all := All() assert.Len(t, all, 2)
assert.Len(t, all, 2)
item, err := Find(1)
item, err := Find(1) require.Nil(t, err)
require.Nil(t, err) assert.Equal(t, int64(1), item.Id)
assert.Equal(t, int64(1), item.Id)
err = item.Delete()
err = item.Delete() require.Nil(t, err)
require.Nil(t, err)
all = All()
all = All() assert.Len(t, all, 1)
assert.Len(t, all, 1) })
}
t.Run("Test Close", func(t *testing.T) {
func TestService_CheckService(t *testing.T) { assert.Nil(t, db.Close())
item, err := Find(2) })
require.Nil(t, err)
hitsCount := item.AllHits().Count()
failsCount := item.AllFailures().Count()
assert.Equal(t, 3, hitsCount)
assert.Equal(t, 2, failsCount)
item.CheckService(true)
assert.Equal(t, 4, hitsCount)
assert.Equal(t, 2, failsCount)
}
func TestClose(t *testing.T) {
assert.Nil(t, db.Close())
} }

View File

@ -33,10 +33,8 @@ func HashPassword(password string) string {
func NewSHA256Hash() string { func NewSHA256Hash() string {
d := make([]byte, 10) d := make([]byte, 10)
rand.Seed(Now().UnixNano()) rand.Seed(Now().UnixNano())
if _, err := rand.Read(d); err == nil { rand.Read(d)
fmt.Printf("%x", sha256.Sum256(d)) return fmt.Sprintf("%x", sha256.Sum256(d))
}
return fmt.Sprintf("%x", d)
} }
var characterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") var characterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")

View File

@ -50,7 +50,6 @@ func TestDir(t *testing.T) {
} }
func TestCommand(t *testing.T) { func TestCommand(t *testing.T) {
t.SkipNow()
in, out, err := Command("pwd") in, out, err := Command("pwd")
assert.Nil(t, err) assert.Nil(t, err)
assert.Contains(t, in, "statping") assert.Contains(t, in, "statping")
@ -153,7 +152,11 @@ func TestHashPassword(t *testing.T) {
} }
func TestNewSHA1Hash(t *testing.T) { func TestNewSHA1Hash(t *testing.T) {
assert.NotEmpty(t, NewSHA1Hash(5)) hash := NewSHA256Hash()
assert.NotEmpty(t, hash)
assert.Len(t, hash, 64)
assert.Len(t, NewSHA256Hash(), 64)
assert.NotEqual(t, hash, NewSHA256Hash())
} }
func TestRandomString(t *testing.T) { func TestRandomString(t *testing.T) {