pull/78/head v0.64
Hunter Long 2018-09-18 23:12:42 -07:00
parent 0a1b63fa76
commit 8dbf573667
8 changed files with 65 additions and 55 deletions

View File

@ -172,6 +172,9 @@ docker-push-latest:
docker push hunterlong/statup:latest
docker push hunterlong/statup:latest-v$(VERSION)
docker-run-mssql:
docker run -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=PaSsW0rD123' -p 1433:1433 -d microsoft/mssql-server-linux
# create Postgres, and MySQL instance using Docker (used for testing)
databases:
docker run --name statup_postgres -p 5432:5432 -e POSTGRES_PASSWORD=password123 -e POSTGRES_USER=root -e POSTGRES_DB=root -d postgres

View File

@ -52,7 +52,13 @@ func Clean() {
utils.DeleteDirectory(dir + "/logs")
}
func RunInit(t *testing.T) {
func RunInit(db string, t *testing.T) {
if db == "mssql" {
os.Setenv("DB_DATABASE", "tempdb")
os.Setenv("DB_PASS", "PaSsW0rD123")
os.Setenv("DB_PORT", "1433")
os.Setenv("DB_USER", "sa")
}
source.Assets()
Clean()
route = handlers.Router()
@ -69,7 +75,7 @@ func TestRunAll(t *testing.T) {
for _, dbt := range databases {
t.Run(dbt+" init", func(t *testing.T) {
RunInit(t)
RunInit(dbt, t)
})
t.Run(dbt+" Save Config", func(t *testing.T) {
RunSaveConfig(t, dbt)
@ -206,6 +212,11 @@ func TestRunAll(t *testing.T) {
t.Run(dbt+" Cleanup", func(t *testing.T) {
core.Configs.Close()
core.DbSession = nil
if dbt == "mssql" {
os.Setenv("DB_DATABASE", "root")
os.Setenv("DB_PASS", "password123")
os.Setenv("DB_PORT", "1433")
}
//Clean()
})
@ -220,6 +231,8 @@ func RunSaveConfig(t *testing.T, db string) {
port := 5432
if db == "mysql" {
port = 3306
} else if db == "mssql" {
port = 1433
}
core.Configs = &core.DbConfig{DbConfig: &types.DbConfig{
DbConn: db,

View File

@ -163,12 +163,7 @@ func (s *Service) SmallText() string {
}
func (s *Service) DowntimeText() string {
lastFailure := s.lastFailure()
if lastFailure == nil {
return ""
}
got, _ := timeago.TimeAgoWithTime(time.Now().UTC().Add(s.Downtime()), time.Now().UTC())
return fmt.Sprintf("Reported offline %v, %v", got, lastFailure.ParseError())
return fmt.Sprintf("%v has been offline for %v", s.Name, utils.DurationReadable(s.Downtime()))
}
// GroupDataBy returns a SQL query as a string to group a column by a time
@ -188,13 +183,13 @@ func GroupDataBy(column string, id int64, start, end time.Time, increment string
// Downtime returns the amount of time of a offline service
func (s *Service) Downtime() time.Duration {
hits, _ := s.Hits()
if len(hits) == 0 {
return time.Duration(0)
}
fails := s.LimitedFailures()
if len(fails) == 0 {
return time.Duration(0)
}
if len(hits) == 0 {
return time.Now().UTC().Sub(fails[len(fails)-1].CreatedAt.UTC())
}
since := fails[0].CreatedAt.UTC().Sub(hits[0].CreatedAt.UTC())
return since
}

32
dev/docker-compose.yml Normal file
View File

@ -0,0 +1,32 @@
postgres:
container_name: postgres
image: postgres
restart: always
ports:
- 5432:5432
environment:
POSTGRES_PASSWORD: password123
POSTGRES_USER: root
POSTGRES_DB: root
mysql:
container_name: mysql
image: mysql:5.6
restart: always
ports:
- 3306:3306
environment:
MYSQL_ROOT_PASSWORD: password123
MYSQL_DATABASE: root
MYSQL_USER: root
MYSQL_PASSWORD: password123
mssql:
container_name: mssql
image: microsoft/mssql-server-linux
restart: always
ports:
- 1433:1433
environment:
SA_PASSWORD: PaSsW0rD123
ACCEPT_EULA: "Y"

View File

@ -23,7 +23,6 @@ import (
"github.com/hunterlong/statup/utils"
"net/http"
"os"
"time"
)
type ApiResponse struct {
@ -94,38 +93,6 @@ func apiServiceHandler(w http.ResponseWriter, r *http.Request) {
json.NewEncoder(w).Encode(service)
}
func apiServiceDataHandler(w http.ResponseWriter, r *http.Request) {
if !isAPIAuthorized(r) {
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
return
}
vars := mux.Vars(r)
fields := parseGet(r)
startField := utils.StringInt(fields.Get("start"))
endField := utils.StringInt(fields.Get("end"))
var start time.Time
var end time.Time
if startField == 0 {
start = time.Now().Add(-24 * time.Hour).UTC()
} else {
start = time.Unix(startField, 0)
}
if endField == 0 {
end = time.Now().UTC()
} else {
end = time.Unix(endField, 0)
}
service := core.SelectService(utils.StringInt(vars["id"]))
if service == nil {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(core.GraphDataRaw(service, start, end).Array)
}
func apiCreateServiceHandler(w http.ResponseWriter, r *http.Request) {
if !isAPIAuthorized(r) {
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)

View File

@ -121,16 +121,6 @@ func TestApiServiceHandler(t *testing.T) {
assert.Equal(t, "https://google.com", obj.Domain)
}
func TestApiServiceDataHandler(t *testing.T) {
rr, err := httpRequestAPI(t, "GET", "/api/services/1/data", nil)
assert.Nil(t, err)
body := rr.Body.String()
var obj []*core.DateScan
formatJSON(body, &obj)
assert.Equal(t, 200, rr.Code)
assert.Equal(t, 60, len(obj))
}
func TestApiCreateServiceHandler(t *testing.T) {
rr, err := httpRequestAPI(t, "POST", "/api/services", strings.NewReader(NEW_HTTP_SERVICE))
assert.Nil(t, err)

View File

@ -84,7 +84,6 @@ func Router() *mux.Router {
r.Handle("/api/services", http.HandlerFunc(apiAllServicesHandler)).Methods("GET")
r.Handle("/api/services", http.HandlerFunc(apiCreateServiceHandler)).Methods("POST")
r.Handle("/api/services/{id}", http.HandlerFunc(apiServiceHandler)).Methods("GET")
r.Handle("/api/services/{id}/data", http.HandlerFunc(apiServiceDataHandler)).Methods("GET")
r.Handle("/api/services/{id}", http.HandlerFunc(apiServiceUpdateHandler)).Methods("POST")
r.Handle("/api/services/{id}", http.HandlerFunc(apiServiceDeleteHandler)).Methods("DELETE")

View File

@ -190,3 +190,14 @@ func copyAndCapture(w io.Writer, r io.Reader) ([]byte, error) {
}
}
}
func DurationReadable(d time.Duration) string {
if d.Hours() >= 1 {
return fmt.Sprintf("%0.0f hours and %0.0f minutes", d.Hours(), d.Minutes())
} else if d.Minutes() >= 1 {
return fmt.Sprintf("%0.0f minutes", d.Minutes())
} else if d.Seconds() >= 1 {
return fmt.Sprintf("%0.0f seconds", d.Seconds())
}
return d.String()
}