mirror of
https://github.com/hamburghammer/gsave.git
synced 2025-03-15 02:25:55 +01:00
Merge branch 'feature/hosts-testing' into develop
Add CI/CD pipeline with drone ci Add application logging Add flags to configure the server
This commit is contained in:
commit
96f1638564
8 changed files with 897 additions and 38 deletions
37
.drone.yml
Normal file
37
.drone.yml
Normal file
|
@ -0,0 +1,37 @@
|
|||
kind: pipeline
|
||||
type: docker
|
||||
name: default
|
||||
|
||||
steps:
|
||||
- name: unit-test
|
||||
image: golang
|
||||
volumes:
|
||||
- name: cache
|
||||
path: /go
|
||||
commands:
|
||||
- go mod download
|
||||
- go test -coverprofile=coverage.out -covermode=count ./...
|
||||
- go tool cover -html=coverage.out -o coverage.html
|
||||
- go tool cover -func=coverage.out | grep total
|
||||
|
||||
- name: race-test
|
||||
image: golang
|
||||
volumes:
|
||||
- name: cache
|
||||
path: /go
|
||||
commands:
|
||||
- go mod download
|
||||
- go test -race -short ./...
|
||||
|
||||
- name: build
|
||||
image: golang
|
||||
volumes:
|
||||
- name: cache
|
||||
path: /go
|
||||
commands:
|
||||
- go mod download
|
||||
- go build
|
||||
|
||||
volumes:
|
||||
- name: cache
|
||||
temp: {}
|
16
README.md
16
README.md
|
@ -1,12 +1,14 @@
|
|||
# gsave
|
||||
[](https://cloud.drone.io/hamburghammer/gsave)
|
||||
|
||||
Database to save all your data from [gstat](https://github.com/hamburghammer/gstat).
|
||||
In the near future [gmon](https://github.com/hamburghammer/gmon) should use it to monitor hosts and to create alerts.
|
||||
|
||||
## TODO
|
||||
- [] Configure CI/CD pipeline
|
||||
- [] HTTP testing
|
||||
- [] Auth Middleware with Basic Auth
|
||||
- [] Flag configurable
|
||||
- [] Logging
|
||||
- [] SQLite DB implementation
|
||||
- [] Env Variable configurable
|
||||
- [x] Configure CI/CD pipeline
|
||||
- [x] HTTP testing
|
||||
- [ ] Auth Middleware with Basic Auth
|
||||
- [x] Flag configurable
|
||||
- [x] Logging
|
||||
- [ ] SQLite DB implementation
|
||||
- [ ] Env Variable configurable
|
||||
|
|
|
@ -1,6 +1,19 @@
|
|||
package controller
|
||||
|
||||
import "github.com/gorilla/mux"
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
var (
|
||||
logPackage = log.WithField("Package", "controller")
|
||||
logRequestError = logPackage.WithField("RequestStatus", "Error")
|
||||
logBadRequest = logRequestError.WithField("StatusCode", http.StatusBadRequest)
|
||||
logNotFound = logRequestError.WithField("StatusCode", http.StatusNotFound)
|
||||
logInternalServerError = logRequestError.WithField("StatusCode", http.StatusInternalServerError)
|
||||
)
|
||||
|
||||
// Router is an interface that should be implemented by any controller
|
||||
// to give some information and to register the routes.
|
||||
|
|
|
@ -4,7 +4,6 @@ import (
|
|||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
|
@ -26,10 +25,10 @@ type HostsRouter struct {
|
|||
// Register registers all routes to the given subrouter.
|
||||
func (hr *HostsRouter) Register(subrouter *mux.Router) {
|
||||
hr.subrouter = subrouter
|
||||
subrouter.HandleFunc("", hr.getHosts).Methods(http.MethodGet).Name("GetHosts")
|
||||
subrouter.HandleFunc("/{hostname}", hr.getHost).Methods(http.MethodGet).Name("GetHost")
|
||||
subrouter.HandleFunc("/{hostname}/stats", hr.getStats).Methods(http.MethodGet).Name("GetStats")
|
||||
subrouter.HandleFunc("/{hostname}/stats", hr.postStats).Methods(http.MethodPost).Name("PostStats")
|
||||
subrouter.HandleFunc("", hr.GetHosts).Methods(http.MethodGet).Name("GetHosts")
|
||||
subrouter.HandleFunc("/{hostname}", hr.GetHost).Methods(http.MethodGet).Name("GetHost")
|
||||
subrouter.HandleFunc("/{hostname}/stats", hr.GetStats).Methods(http.MethodGet).Name("GetStats")
|
||||
subrouter.HandleFunc("/{hostname}/stats", hr.PostStats).Methods(http.MethodPost).Name("PostStats")
|
||||
}
|
||||
|
||||
// GetPrefix returns the the pre route for this controller.
|
||||
|
@ -42,10 +41,12 @@ func (hr *HostsRouter) GetRouteName() string {
|
|||
return "Hosts"
|
||||
}
|
||||
|
||||
func (hr *HostsRouter) getHosts(w http.ResponseWriter, r *http.Request) {
|
||||
// GetHosts is a HandleFunc to get hosts out of the db with optional pagination as query params.
|
||||
func (hr *HostsRouter) GetHosts(w http.ResponseWriter, r *http.Request) {
|
||||
pagination, err := hr.getSkipAndLimit(r)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
logBadRequest.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -53,9 +54,11 @@ func (hr *HostsRouter) getHosts(w http.ResponseWriter, r *http.Request) {
|
|||
if err != nil {
|
||||
if errors.Is(err, db.ErrHostsNotFound) || errors.Is(err, db.ErrAllEntriesSkipped) {
|
||||
http.Error(w, err.Error(), http.StatusNotFound)
|
||||
logNotFound.Error(err)
|
||||
return
|
||||
}
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
logInternalServerError.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -63,41 +66,50 @@ func (hr *HostsRouter) getHosts(w http.ResponseWriter, r *http.Request) {
|
|||
json.NewEncoder(w).Encode(hosts)
|
||||
}
|
||||
|
||||
func (hr *HostsRouter) getHost(w http.ResponseWriter, r *http.Request) {
|
||||
// GetHost is a HandleFunc to get one host. The host name gets read out of the request path.
|
||||
func (hr *HostsRouter) GetHost(w http.ResponseWriter, r *http.Request) {
|
||||
hostname := mux.Vars(r)["hostname"]
|
||||
if hostname == "" {
|
||||
http.Error(w, fmt.Sprintf("Missing hostname: '%s' is not a valid hostname\n", hostname), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
host, err := hr.db.GetHost(hostname)
|
||||
if err != nil {
|
||||
if errors.Is(err, db.ErrHostNotFound) {
|
||||
http.Error(w, fmt.Sprintf("No host with the name '%s' found\n", hostname), http.StatusNotFound)
|
||||
http.Error(w, fmt.Sprintf("No host with the name '%s' found", hostname), http.StatusNotFound)
|
||||
logNotFound.Error(err)
|
||||
return
|
||||
}
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
logInternalServerError.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(host)
|
||||
}
|
||||
|
||||
func (hr *HostsRouter) getStats(w http.ResponseWriter, r *http.Request) {
|
||||
// GetStats is a HandleFunc to get paginated stats for a host.
|
||||
func (hr *HostsRouter) GetStats(w http.ResponseWriter, r *http.Request) {
|
||||
hostname := mux.Vars(r)["hostname"]
|
||||
|
||||
pagination, err := hr.getSkipAndLimit(r)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
logBadRequest.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
stats, err := hr.db.GetStatsByHostname(hostname, pagination)
|
||||
if err != nil {
|
||||
if errors.Is(err, db.ErrHostsNotFound) || errors.Is(err, db.ErrAllEntriesSkipped) {
|
||||
http.Error(w, err.Error(), http.StatusNotFound)
|
||||
if errors.Is(err, db.ErrHostNotFound) {
|
||||
http.Error(w, fmt.Sprintf("No host with the name '%s' found", hostname), http.StatusNotFound)
|
||||
logNotFound.Error(err)
|
||||
return
|
||||
} else if errors.Is(err, db.ErrAllEntriesSkipped) {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
logNotFound.Error(err)
|
||||
return
|
||||
}
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
logInternalServerError.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -105,23 +117,25 @@ func (hr *HostsRouter) getStats(w http.ResponseWriter, r *http.Request) {
|
|||
json.NewEncoder(w).Encode(stats)
|
||||
}
|
||||
|
||||
func (hr *HostsRouter) postStats(w http.ResponseWriter, r *http.Request) {
|
||||
// PostStats is a HandleFunc to insert a new data point into the db.
|
||||
func (hr *HostsRouter) PostStats(w http.ResponseWriter, r *http.Request) {
|
||||
hostname := mux.Vars(r)["hostname"]
|
||||
|
||||
var stats db.Stats
|
||||
err := json.NewDecoder(r.Body).Decode(&stats)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
log.Println(err)
|
||||
http.Error(w, "Could not read the body", http.StatusBadRequest)
|
||||
logBadRequest.Error(fmt.Sprintf("JSON error decoding new stat: %v", err))
|
||||
return
|
||||
}
|
||||
log.Printf("Received stat: %+v", stats)
|
||||
|
||||
err = hr.db.InsertStats(hostname, stats)
|
||||
if err != nil {
|
||||
http.Error(w, "Something with the DB went wrong.", http.StatusInternalServerError)
|
||||
logInternalServerError.Error(err)
|
||||
return
|
||||
}
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
}
|
||||
|
||||
// getSkipAndLimit from the query of the request.
|
||||
|
@ -137,6 +151,9 @@ func (hr *HostsRouter) getSkipAndLimit(r *http.Request) (db.Pagination, error) {
|
|||
if err != nil {
|
||||
return db.Pagination{}, fmt.Errorf("Query param 'limit' expected to be a number: %s is not a number", strLimit)
|
||||
}
|
||||
if limit < 0 {
|
||||
return db.Pagination{}, fmt.Errorf("No negative number allowed for the query param 'limit'")
|
||||
}
|
||||
|
||||
strSkip := r.FormValue("skip")
|
||||
if strSkip == "" {
|
||||
|
@ -146,6 +163,9 @@ func (hr *HostsRouter) getSkipAndLimit(r *http.Request) (db.Pagination, error) {
|
|||
if err != nil {
|
||||
return db.Pagination{}, fmt.Errorf("Query param 'skip' expected to be a number: %s is not a number", strSkip)
|
||||
}
|
||||
if skip < 0 {
|
||||
return db.Pagination{}, fmt.Errorf("No negative number allowed for the query param 'skip'")
|
||||
}
|
||||
|
||||
return db.Pagination{Skip: int(skip), Limit: int(limit)}, nil
|
||||
}
|
||||
|
|
753
controller/hosts_test.go
Normal file
753
controller/hosts_test.go
Normal file
|
@ -0,0 +1,753 @@
|
|||
package controller_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/hamburghammer/gsave/controller"
|
||||
"github.com/hamburghammer/gsave/db"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestHostsRouter_GetHosts(t *testing.T) {
|
||||
t.Run("db has one item", func(t *testing.T) {
|
||||
stats := []db.HostInfo{
|
||||
{Hostname: "foo"},
|
||||
}
|
||||
hostDB := &MockHostDB{}
|
||||
hostDB.SetHosts(stats)
|
||||
hostsRouter := controller.NewHostsRouter(hostDB)
|
||||
|
||||
req, err := http.NewRequest("GET", "/hosts", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
rr := httptest.NewRecorder()
|
||||
handler := http.HandlerFunc(hostsRouter.GetHosts)
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, rr.Code)
|
||||
assert.Equal(t, "application/json", rr.Header().Get("Content-Type"))
|
||||
|
||||
var gotBody []db.HostInfo
|
||||
json.Unmarshal(rr.Body.Bytes(), &gotBody)
|
||||
|
||||
assert.Equal(t, stats, gotBody)
|
||||
})
|
||||
|
||||
t.Run("db is empty", func(t *testing.T) {
|
||||
stats := []db.HostInfo{}
|
||||
hostDB := &MockHostDB{}
|
||||
hostDB.SetHosts(stats)
|
||||
hostsRouter := controller.NewHostsRouter(hostDB)
|
||||
|
||||
req, err := http.NewRequest("GET", "/hosts", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
rr := httptest.NewRecorder()
|
||||
handler := http.HandlerFunc(hostsRouter.GetHosts)
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, rr.Code)
|
||||
|
||||
var gotBody []db.HostInfo
|
||||
json.Unmarshal(rr.Body.Bytes(), &gotBody)
|
||||
|
||||
assert.Equal(t, stats, gotBody)
|
||||
})
|
||||
|
||||
t.Run("db returns hosts not found error", func(t *testing.T) {
|
||||
hostDB := &MockHostDB{}
|
||||
hostDB.SetHostsError(db.ErrHostsNotFound)
|
||||
hostsRouter := controller.NewHostsRouter(hostDB)
|
||||
|
||||
req, err := http.NewRequest("GET", "/hosts", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
rr := httptest.NewRecorder()
|
||||
handler := http.HandlerFunc(hostsRouter.GetHosts)
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(t, http.StatusNotFound, rr.Code)
|
||||
|
||||
wantBody := fmt.Sprintf("%s\n", db.ErrHostsNotFound.Error())
|
||||
assert.Equal(t, wantBody, rr.Body.String())
|
||||
})
|
||||
|
||||
t.Run("db returns all entities skipped error", func(t *testing.T) {
|
||||
hostDB := &MockHostDB{}
|
||||
hostDB.SetHostsError(db.ErrAllEntriesSkipped)
|
||||
hostsRouter := controller.NewHostsRouter(hostDB)
|
||||
|
||||
req, err := http.NewRequest("GET", "/hosts", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
rr := httptest.NewRecorder()
|
||||
handler := http.HandlerFunc(hostsRouter.GetHosts)
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(t, http.StatusNotFound, rr.Code)
|
||||
|
||||
wantBody := fmt.Sprintf("%s\n", db.ErrAllEntriesSkipped.Error())
|
||||
assert.Equal(t, wantBody, rr.Body.String())
|
||||
})
|
||||
|
||||
t.Run("db returns unknown error", func(t *testing.T) {
|
||||
unknownErr := errors.New("some error")
|
||||
hostDB := &MockHostDB{}
|
||||
hostDB.SetHostsError(unknownErr)
|
||||
hostsRouter := controller.NewHostsRouter(hostDB)
|
||||
|
||||
req, err := http.NewRequest("GET", "/hosts", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
rr := httptest.NewRecorder()
|
||||
handler := http.HandlerFunc(hostsRouter.GetHosts)
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(t, http.StatusInternalServerError, rr.Code)
|
||||
|
||||
wantBody := fmt.Sprintf("%s\n", unknownErr.Error())
|
||||
assert.Equal(t, wantBody, rr.Body.String())
|
||||
})
|
||||
|
||||
t.Run("pagination", func(t *testing.T) {
|
||||
t.Run("default pagination has a limit of 10", func(t *testing.T) {
|
||||
hostDB := &MockHostDB{}
|
||||
hostsRouter := controller.NewHostsRouter(hostDB)
|
||||
|
||||
req, err := http.NewRequest("GET", "/hosts", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
rr := httptest.NewRecorder()
|
||||
handler := http.HandlerFunc(hostsRouter.GetHosts)
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.NotEqual(t, db.Pagination{}, hostDB.GetPagination())
|
||||
assert.Equal(t, 10, hostDB.GetPagination().Limit)
|
||||
})
|
||||
|
||||
t.Run("default pagination has a skip of 0", func(t *testing.T) {
|
||||
hostDB := &MockHostDB{}
|
||||
hostsRouter := controller.NewHostsRouter(hostDB)
|
||||
|
||||
req, err := http.NewRequest("GET", "/hosts", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
rr := httptest.NewRecorder()
|
||||
handler := http.HandlerFunc(hostsRouter.GetHosts)
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.NotEqual(t, db.Pagination{}, hostDB.GetPagination())
|
||||
assert.Equal(t, 0, hostDB.GetPagination().Skip)
|
||||
})
|
||||
|
||||
t.Run("sets custom limit", func(t *testing.T) {
|
||||
hostDB := &MockHostDB{}
|
||||
hostsRouter := controller.NewHostsRouter(hostDB)
|
||||
|
||||
req, err := http.NewRequest("GET", "/hosts?limit=2", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
rr := httptest.NewRecorder()
|
||||
handler := http.HandlerFunc(hostsRouter.GetHosts)
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, rr.Code)
|
||||
|
||||
assert.NotEqual(t, db.Pagination{}, hostDB.GetPagination())
|
||||
assert.Equal(t, 2, hostDB.GetPagination().Limit)
|
||||
})
|
||||
|
||||
t.Run("sets negative limit", func(t *testing.T) {
|
||||
hostDB := &MockHostDB{}
|
||||
hostsRouter := controller.NewHostsRouter(hostDB)
|
||||
|
||||
req, err := http.NewRequest("GET", "/hosts?limit=-2", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
rr := httptest.NewRecorder()
|
||||
handler := http.HandlerFunc(hostsRouter.GetHosts)
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(t, http.StatusBadRequest, rr.Code)
|
||||
|
||||
wantErr := "No negative number allowed for the query param 'limit'\n"
|
||||
assert.Equal(t, wantErr, rr.Body.String())
|
||||
})
|
||||
|
||||
t.Run("sets negative skip", func(t *testing.T) {
|
||||
hostDB := &MockHostDB{}
|
||||
hostsRouter := controller.NewHostsRouter(hostDB)
|
||||
|
||||
req, err := http.NewRequest("GET", "/hosts?skip=-2", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
rr := httptest.NewRecorder()
|
||||
handler := http.HandlerFunc(hostsRouter.GetHosts)
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(t, http.StatusBadRequest, rr.Code)
|
||||
|
||||
wantErr := "No negative number allowed for the query param 'skip'\n"
|
||||
assert.Equal(t, wantErr, rr.Body.String())
|
||||
})
|
||||
|
||||
t.Run("sets skip to not a number", func(t *testing.T) {
|
||||
hostDB := &MockHostDB{}
|
||||
hostsRouter := controller.NewHostsRouter(hostDB)
|
||||
|
||||
req, err := http.NewRequest("GET", "/hosts?skip=a", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
rr := httptest.NewRecorder()
|
||||
handler := http.HandlerFunc(hostsRouter.GetHosts)
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(t, http.StatusBadRequest, rr.Code)
|
||||
|
||||
wantErr := "Query param 'skip' expected to be a number: a is not a number\n"
|
||||
assert.Equal(t, wantErr, rr.Body.String())
|
||||
})
|
||||
|
||||
t.Run("sets limit to not a number", func(t *testing.T) {
|
||||
hostDB := &MockHostDB{}
|
||||
hostsRouter := controller.NewHostsRouter(hostDB)
|
||||
|
||||
req, err := http.NewRequest("GET", "/hosts?limit=a", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
rr := httptest.NewRecorder()
|
||||
handler := http.HandlerFunc(hostsRouter.GetHosts)
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(t, http.StatusBadRequest, rr.Code)
|
||||
|
||||
wantErr := "Query param 'limit' expected to be a number: a is not a number\n"
|
||||
assert.Equal(t, wantErr, rr.Body.String())
|
||||
})
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetHost(t *testing.T) {
|
||||
t.Run("search with hostname from url", func(t *testing.T) {
|
||||
hostname := "foo"
|
||||
hostInfo := db.HostInfo{Hostname: hostname, DataPoints: 1}
|
||||
hostDB := &MockHostDB{}
|
||||
hostDB.SetHost(hostInfo)
|
||||
hostsRouter := controller.NewHostsRouter(hostDB)
|
||||
|
||||
req, err := http.NewRequest("GET", "/"+hostname, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
req = mux.SetURLVars(req, map[string]string{"hostname": hostname})
|
||||
|
||||
rr := httptest.NewRecorder()
|
||||
handler := http.HandlerFunc(hostsRouter.GetHost)
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(t, hostname, hostDB.GetHostHostname())
|
||||
})
|
||||
|
||||
t.Run("db has an item", func(t *testing.T) {
|
||||
hostname := "foo"
|
||||
hostInfo := db.HostInfo{Hostname: hostname, DataPoints: 1}
|
||||
hostDB := &MockHostDB{}
|
||||
hostDB.SetHost(hostInfo)
|
||||
hostsRouter := controller.NewHostsRouter(hostDB)
|
||||
|
||||
req, err := http.NewRequest("GET", "/"+hostname, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
req = mux.SetURLVars(req, map[string]string{"hostname": hostname})
|
||||
|
||||
rr := httptest.NewRecorder()
|
||||
handler := http.HandlerFunc(hostsRouter.GetHost)
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, rr.Code)
|
||||
assert.Equal(t, "application/json", rr.Header().Get("Content-Type"))
|
||||
|
||||
var gotBody db.HostInfo
|
||||
err = json.NewDecoder(rr.Body).Decode(&gotBody)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assert.Equal(t, hostInfo, gotBody)
|
||||
})
|
||||
|
||||
t.Run("db returns not found error", func(t *testing.T) {
|
||||
hostname := "foo"
|
||||
hostDB := &MockHostDB{}
|
||||
hostDB.SetHostError(db.ErrHostNotFound)
|
||||
hostsRouter := controller.NewHostsRouter(hostDB)
|
||||
|
||||
req, err := http.NewRequest("GET", "/"+hostname, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
req = mux.SetURLVars(req, map[string]string{"hostname": hostname})
|
||||
|
||||
rr := httptest.NewRecorder()
|
||||
handler := http.HandlerFunc(hostsRouter.GetHost)
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(t, http.StatusNotFound, rr.Code)
|
||||
|
||||
wantErr := fmt.Sprintf("No host with the name '%s' found\n", hostname)
|
||||
assert.Equal(t, wantErr, rr.Body.String())
|
||||
})
|
||||
|
||||
t.Run("db returns unknown error", func(t *testing.T) {
|
||||
unknownErr := errors.New("unknown error")
|
||||
hostname := "foo"
|
||||
hostDB := &MockHostDB{}
|
||||
hostDB.SetHostError(unknownErr)
|
||||
hostsRouter := controller.NewHostsRouter(hostDB)
|
||||
|
||||
req, err := http.NewRequest("GET", "/"+hostname, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
req = mux.SetURLVars(req, map[string]string{"hostname": hostname})
|
||||
|
||||
rr := httptest.NewRecorder()
|
||||
handler := http.HandlerFunc(hostsRouter.GetHost)
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(t, http.StatusInternalServerError, rr.Code)
|
||||
|
||||
wantErr := fmt.Sprintf("%s\n", unknownErr.Error())
|
||||
assert.Equal(t, wantErr, rr.Body.String())
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetStat(t *testing.T) {
|
||||
t.Run("pagination", func(t *testing.T) {
|
||||
t.Run("default pagination has a limit of 10", func(t *testing.T) {
|
||||
hostname := "foo"
|
||||
hostDB := &MockHostDB{}
|
||||
hostsRouter := controller.NewHostsRouter(hostDB)
|
||||
|
||||
req, err := http.NewRequest("GET", "/"+hostname+"/stats", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
rr := httptest.NewRecorder()
|
||||
handler := http.HandlerFunc(hostsRouter.GetStats)
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.NotEqual(t, db.Pagination{}, hostDB.GetPagination())
|
||||
assert.Equal(t, 10, hostDB.GetPagination().Limit)
|
||||
})
|
||||
|
||||
t.Run("default pagination has a skip of 0", func(t *testing.T) {
|
||||
hostname := "foo"
|
||||
hostDB := &MockHostDB{}
|
||||
hostsRouter := controller.NewHostsRouter(hostDB)
|
||||
|
||||
req, err := http.NewRequest("GET", "/"+hostname+"/stats", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
rr := httptest.NewRecorder()
|
||||
handler := http.HandlerFunc(hostsRouter.GetStats)
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.NotEqual(t, db.Pagination{}, hostDB.GetPagination())
|
||||
assert.Equal(t, 0, hostDB.GetPagination().Skip)
|
||||
})
|
||||
|
||||
t.Run("sets custom limit", func(t *testing.T) {
|
||||
hostname := "foo"
|
||||
hostDB := &MockHostDB{}
|
||||
hostsRouter := controller.NewHostsRouter(hostDB)
|
||||
|
||||
req, err := http.NewRequest("GET", "/"+hostname+"/stats?limit=2", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
rr := httptest.NewRecorder()
|
||||
handler := http.HandlerFunc(hostsRouter.GetStats)
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, rr.Code)
|
||||
|
||||
assert.NotEqual(t, db.Pagination{}, hostDB.GetPagination())
|
||||
assert.Equal(t, 2, hostDB.GetPagination().Limit)
|
||||
})
|
||||
|
||||
t.Run("sets negative limit", func(t *testing.T) {
|
||||
hostname := "foo"
|
||||
hostDB := &MockHostDB{}
|
||||
hostsRouter := controller.NewHostsRouter(hostDB)
|
||||
|
||||
req, err := http.NewRequest("GET", "/"+hostname+"/stats?limit=-2", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
rr := httptest.NewRecorder()
|
||||
handler := http.HandlerFunc(hostsRouter.GetStats)
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(t, http.StatusBadRequest, rr.Code)
|
||||
|
||||
wantErr := "No negative number allowed for the query param 'limit'\n"
|
||||
assert.Equal(t, wantErr, rr.Body.String())
|
||||
})
|
||||
|
||||
t.Run("sets negative skip", func(t *testing.T) {
|
||||
hostname := "foo"
|
||||
hostDB := &MockHostDB{}
|
||||
hostsRouter := controller.NewHostsRouter(hostDB)
|
||||
|
||||
req, err := http.NewRequest("GET", "/"+hostname+"/stats?skip=-2", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
rr := httptest.NewRecorder()
|
||||
handler := http.HandlerFunc(hostsRouter.GetStats)
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(t, http.StatusBadRequest, rr.Code)
|
||||
|
||||
wantErr := "No negative number allowed for the query param 'skip'\n"
|
||||
assert.Equal(t, wantErr, rr.Body.String())
|
||||
})
|
||||
|
||||
t.Run("sets skip to not a number", func(t *testing.T) {
|
||||
hostname := "foo"
|
||||
hostDB := &MockHostDB{}
|
||||
hostsRouter := controller.NewHostsRouter(hostDB)
|
||||
|
||||
req, err := http.NewRequest("GET", "/"+hostname+"/stats?skip=a", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
rr := httptest.NewRecorder()
|
||||
handler := http.HandlerFunc(hostsRouter.GetStats)
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(t, http.StatusBadRequest, rr.Code)
|
||||
|
||||
wantErr := "Query param 'skip' expected to be a number: a is not a number\n"
|
||||
assert.Equal(t, wantErr, rr.Body.String())
|
||||
})
|
||||
|
||||
t.Run("sets limit to not a number", func(t *testing.T) {
|
||||
hostname := "foo"
|
||||
hostDB := &MockHostDB{}
|
||||
hostsRouter := controller.NewHostsRouter(hostDB)
|
||||
|
||||
req, err := http.NewRequest("GET", "/"+hostname+"/stats?limit=a", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
rr := httptest.NewRecorder()
|
||||
handler := http.HandlerFunc(hostsRouter.GetStats)
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(t, http.StatusBadRequest, rr.Code)
|
||||
|
||||
wantErr := "Query param 'limit' expected to be a number: a is not a number\n"
|
||||
assert.Equal(t, wantErr, rr.Body.String())
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("search with hostname from url", func(t *testing.T) {
|
||||
hostname := "foo"
|
||||
hostInfo := db.HostInfo{Hostname: hostname, DataPoints: 1}
|
||||
hostDB := &MockHostDB{}
|
||||
hostDB.SetHost(hostInfo)
|
||||
hostsRouter := controller.NewHostsRouter(hostDB)
|
||||
|
||||
req, err := http.NewRequest("GET", "/"+hostname+"/stats", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
req = mux.SetURLVars(req, map[string]string{"hostname": hostname})
|
||||
|
||||
rr := httptest.NewRecorder()
|
||||
handler := http.HandlerFunc(hostsRouter.GetStats)
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(t, hostname, hostDB.GetStatsByHostnameHostname())
|
||||
})
|
||||
|
||||
t.Run("db has an item", func(t *testing.T) {
|
||||
hostname := "foo"
|
||||
stats := []db.Stats{{Hostname: hostname}}
|
||||
hostDB := &MockHostDB{}
|
||||
hostDB.SetStatsByHostname(stats)
|
||||
hostsRouter := controller.NewHostsRouter(hostDB)
|
||||
|
||||
req, err := http.NewRequest("GET", "/"+hostname+"/stats", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
req = mux.SetURLVars(req, map[string]string{"hostname": hostname})
|
||||
|
||||
rr := httptest.NewRecorder()
|
||||
handler := http.HandlerFunc(hostsRouter.GetStats)
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, rr.Code)
|
||||
assert.Equal(t, hostname, hostDB.GetStatsByHostnameHostname())
|
||||
|
||||
var gotBody []db.Stats
|
||||
err = json.NewDecoder(rr.Body).Decode(&gotBody)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assert.Equal(t, stats, gotBody)
|
||||
})
|
||||
|
||||
t.Run("db returns not found error", func(t *testing.T) {
|
||||
hostname := "foo"
|
||||
hostDB := &MockHostDB{}
|
||||
hostDB.SetStatsByHostnameError(db.ErrHostNotFound)
|
||||
hostsRouter := controller.NewHostsRouter(hostDB)
|
||||
|
||||
req, err := http.NewRequest("GET", "/"+hostname+"/stats", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
req = mux.SetURLVars(req, map[string]string{"hostname": hostname})
|
||||
|
||||
rr := httptest.NewRecorder()
|
||||
handler := http.HandlerFunc(hostsRouter.GetStats)
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(t, http.StatusNotFound, rr.Code)
|
||||
|
||||
wantErr := fmt.Sprintf("No host with the name '%s' found\n", hostname)
|
||||
assert.Equal(t, wantErr, rr.Body.String())
|
||||
})
|
||||
|
||||
t.Run("db returns all entries skipped error", func(t *testing.T) {
|
||||
hostname := "foo"
|
||||
hostDB := &MockHostDB{}
|
||||
hostDB.SetStatsByHostnameError(db.ErrAllEntriesSkipped)
|
||||
hostsRouter := controller.NewHostsRouter(hostDB)
|
||||
|
||||
req, err := http.NewRequest("GET", "/"+hostname+"/stats", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
req = mux.SetURLVars(req, map[string]string{"hostname": hostname})
|
||||
|
||||
rr := httptest.NewRecorder()
|
||||
handler := http.HandlerFunc(hostsRouter.GetStats)
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(t, http.StatusBadRequest, rr.Code)
|
||||
|
||||
wantErr := "db: All entries skipped\n"
|
||||
assert.Equal(t, wantErr, rr.Body.String())
|
||||
})
|
||||
|
||||
t.Run("db returns unknown error", func(t *testing.T) {
|
||||
unknownErr := errors.New("unknown error")
|
||||
hostname := "foo"
|
||||
hostDB := &MockHostDB{}
|
||||
hostDB.SetStatsByHostnameError(unknownErr)
|
||||
hostsRouter := controller.NewHostsRouter(hostDB)
|
||||
|
||||
req, err := http.NewRequest("GET", "/"+hostname+"/stats", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
req = mux.SetURLVars(req, map[string]string{"hostname": hostname})
|
||||
|
||||
rr := httptest.NewRecorder()
|
||||
handler := http.HandlerFunc(hostsRouter.GetStats)
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(t, http.StatusInternalServerError, rr.Code)
|
||||
|
||||
wantErr := fmt.Sprintf("%s\n", unknownErr.Error())
|
||||
assert.Equal(t, wantErr, rr.Body.String())
|
||||
})
|
||||
}
|
||||
|
||||
func TestInsertStat(t *testing.T) {
|
||||
t.Run("insert new stat into the db", func(t *testing.T) {
|
||||
hostname := "foo"
|
||||
stat := db.Stats{Hostname: hostname}
|
||||
hostDB := &MockHostDB{}
|
||||
hostsRouter := controller.NewHostsRouter(hostDB)
|
||||
|
||||
requestBody, _ := json.Marshal(stat)
|
||||
req, err := http.NewRequest("POST", "/"+hostname+"/stats", bytes.NewBuffer(requestBody))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
req = mux.SetURLVars(req, map[string]string{"hostname": hostname})
|
||||
|
||||
rr := httptest.NewRecorder()
|
||||
handler := http.HandlerFunc(hostsRouter.PostStats)
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(t, http.StatusCreated, rr.Code)
|
||||
assert.Equal(t, hostname, hostDB.GetInsertStatsHostname())
|
||||
|
||||
assert.Equal(t, stat, hostDB.GetInsertedStats())
|
||||
})
|
||||
|
||||
t.Run("missing body", func(t *testing.T) {
|
||||
hostname := "foo"
|
||||
hostDB := &MockHostDB{}
|
||||
hostsRouter := controller.NewHostsRouter(hostDB)
|
||||
|
||||
req, err := http.NewRequest("POST", "/"+hostname+"/stats", bytes.NewBuffer([]byte{}))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
req = mux.SetURLVars(req, map[string]string{"hostname": hostname})
|
||||
|
||||
rr := httptest.NewRecorder()
|
||||
handler := http.HandlerFunc(hostsRouter.PostStats)
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(t, http.StatusBadRequest, rr.Code)
|
||||
assert.Equal(t, "Could not read the body\n", rr.Body.String())
|
||||
})
|
||||
|
||||
t.Run("db returns an unknown error", func(t *testing.T) {
|
||||
hostname := "foo"
|
||||
unknownErr := errors.New("unknown error")
|
||||
stat := db.Stats{Hostname: hostname}
|
||||
hostDB := &MockHostDB{}
|
||||
hostDB.SetInsertStatsError(unknownErr)
|
||||
hostsRouter := controller.NewHostsRouter(hostDB)
|
||||
|
||||
requestBody, _ := json.Marshal(stat)
|
||||
req, err := http.NewRequest("POST", "/"+hostname+"/stats", bytes.NewBuffer(requestBody))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
req = mux.SetURLVars(req, map[string]string{"hostname": hostname})
|
||||
|
||||
rr := httptest.NewRecorder()
|
||||
handler := http.HandlerFunc(hostsRouter.PostStats)
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(t, http.StatusInternalServerError, rr.Code)
|
||||
assert.Equal(t, "Something with the DB went wrong.\n", rr.Body.String())
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
type MockHostDB struct {
|
||||
hosts []db.HostInfo
|
||||
hostsError error
|
||||
|
||||
host db.HostInfo
|
||||
hostError error
|
||||
|
||||
stats []db.Stats
|
||||
statsError error
|
||||
|
||||
insertedStat db.Stats
|
||||
insertedStatError error
|
||||
|
||||
pagination db.Pagination
|
||||
hostname string
|
||||
}
|
||||
|
||||
// GetHosts
|
||||
func (m *MockHostDB) SetHosts(hosts []db.HostInfo) {
|
||||
m.hosts = hosts
|
||||
}
|
||||
func (m *MockHostDB) SetHostsError(err error) {
|
||||
m.hostsError = err
|
||||
}
|
||||
func (m *MockHostDB) GetHosts(pagination db.Pagination) ([]db.HostInfo, error) {
|
||||
m.pagination = pagination
|
||||
if m.hostsError != nil {
|
||||
return []db.HostInfo{}, m.hostsError
|
||||
}
|
||||
return m.hosts, nil
|
||||
}
|
||||
|
||||
// GetHost
|
||||
func (m *MockHostDB) SetHost(host db.HostInfo) {
|
||||
m.host = host
|
||||
}
|
||||
func (m *MockHostDB) SetHostError(err error) {
|
||||
m.hostError = err
|
||||
}
|
||||
func (m *MockHostDB) GetHostHostname() string {
|
||||
return m.hostname
|
||||
}
|
||||
func (m *MockHostDB) GetHost(hostname string) (db.HostInfo, error) {
|
||||
m.hostname = hostname
|
||||
if m.hostError != nil {
|
||||
return db.HostInfo{}, m.hostError
|
||||
}
|
||||
return m.host, nil
|
||||
}
|
||||
|
||||
// GetStatsByHostname
|
||||
func (m *MockHostDB) SetStatsByHostname(stats []db.Stats) {
|
||||
m.stats = stats
|
||||
}
|
||||
func (m *MockHostDB) SetStatsByHostnameError(err error) {
|
||||
m.statsError = err
|
||||
}
|
||||
func (m *MockHostDB) GetStatsByHostnameHostname() string {
|
||||
return m.hostname
|
||||
}
|
||||
func (m *MockHostDB) GetStatsByHostname(hostname string, pagination db.Pagination) ([]db.Stats, error) {
|
||||
m.hostname = hostname
|
||||
m.pagination = pagination
|
||||
if m.statsError != nil {
|
||||
return []db.Stats{}, m.statsError
|
||||
}
|
||||
return m.stats, nil
|
||||
}
|
||||
|
||||
// InsertStats
|
||||
func (m *MockHostDB) GetInsertedStats() db.Stats {
|
||||
return m.insertedStat
|
||||
}
|
||||
func (m *MockHostDB) SetInsertStatsError(err error) {
|
||||
m.insertedStatError = err
|
||||
}
|
||||
func (m *MockHostDB) GetInsertStatsHostname() string {
|
||||
return m.hostname
|
||||
}
|
||||
func (m *MockHostDB) InsertStats(hostname string, stats db.Stats) error {
|
||||
m.hostname = hostname
|
||||
m.insertedStat = stats
|
||||
if m.insertedStatError != nil {
|
||||
return m.insertedStatError
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MockHostDB) GetPagination() db.Pagination {
|
||||
return m.pagination
|
||||
}
|
1
go.mod
1
go.mod
|
@ -4,5 +4,6 @@ go 1.15
|
|||
|
||||
require (
|
||||
github.com/gorilla/mux v1.8.0
|
||||
github.com/sirupsen/logrus v1.7.0
|
||||
github.com/stretchr/testify v1.6.1
|
||||
)
|
||||
|
|
7
go.sum
7
go.sum
|
@ -1,12 +1,19 @@
|
|||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
|
||||
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
|
||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
|
|
48
main.go
48
main.go
|
@ -3,8 +3,8 @@ package main
|
|||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
|
@ -14,12 +14,38 @@ import (
|
|||
"github.com/gorilla/mux"
|
||||
"github.com/hamburghammer/gsave/controller"
|
||||
"github.com/hamburghammer/gsave/db"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
const serveAddr = "127.0.0.1:8080"
|
||||
var (
|
||||
servePort int
|
||||
logPackage = log.WithField("Package", "main")
|
||||
)
|
||||
|
||||
func init() {
|
||||
flag.IntVar(&servePort, "port", 8080, "The port for the HTTP server.")
|
||||
verbose := flag.Bool("verbose", false, "Enable debug logging output.")
|
||||
quiet := flag.Bool("quiet", false, "Disable loging output only prints errors.")
|
||||
jsonLogging := flag.Bool("json", false, "Set the logging format to json.")
|
||||
flag.Parse()
|
||||
|
||||
log.SetFormatter(&log.TextFormatter{
|
||||
FullTimestamp: true,
|
||||
})
|
||||
|
||||
if *verbose {
|
||||
log.SetLevel(log.DebugLevel)
|
||||
}
|
||||
if *quiet {
|
||||
log.SetLevel(log.ErrorLevel)
|
||||
}
|
||||
if *jsonLogging {
|
||||
log.SetFormatter(&log.JSONFormatter{})
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
log.Println("Initializing the DB...")
|
||||
logPackage.Info("Initializing the DB...")
|
||||
stats := []db.Stats{
|
||||
{Hostname: "foo", CPU: 0},
|
||||
{Hostname: "foo", CPU: 1},
|
||||
|
@ -27,19 +53,19 @@ func main() {
|
|||
}
|
||||
hostDB, err := initDB(stats)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
logPackage.Fatal(err)
|
||||
}
|
||||
|
||||
log.Println("Initializing the routes...")
|
||||
logPackage.Info("Initializing the routes...")
|
||||
controllers := []controller.Router{
|
||||
controller.NewHostsRouter(hostDB),
|
||||
}
|
||||
router := initRouter(hostDB, controllers)
|
||||
|
||||
log.Println("Starting the HTTP server...")
|
||||
logPackage.Info("Starting the HTTP server...")
|
||||
server := &http.Server{
|
||||
Handler: router,
|
||||
Addr: serveAddr,
|
||||
Addr: fmt.Sprintf(":%d", servePort),
|
||||
WriteTimeout: 15 * time.Second,
|
||||
ReadTimeout: 15 * time.Second,
|
||||
}
|
||||
|
@ -75,13 +101,13 @@ func initRouter(hostDB db.HostDB, controllers []controller.Router) *mux.Router {
|
|||
|
||||
func startHTTPServer(server *http.Server, wg *sync.WaitGroup) {
|
||||
defer wg.Done()
|
||||
log.Printf("The HTTP server is running: http://%s\n", serveAddr)
|
||||
logPackage.Infof("The HTTP server is running: http://localhost:%d/hosts\n", servePort)
|
||||
if err := server.ListenAndServe(); err != nil {
|
||||
if errors.Is(err, http.ErrServerClosed) {
|
||||
log.Println("Shutting down the server...")
|
||||
logPackage.Info("Shutting down the server...")
|
||||
return
|
||||
}
|
||||
log.Fatalf("An unexpected error happend while running the HTTP server: %v\n", err)
|
||||
logPackage.Fatalf("An unexpected error happend while running the HTTP server: %v\n", err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -96,6 +122,6 @@ func listenToStopHTTPServer(server *http.Server, wg *sync.WaitGroup) {
|
|||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
if err := server.Shutdown(ctx); err != nil {
|
||||
log.Printf("An error happened on the shutdown of the server: %v", err)
|
||||
logPackage.Errorf("An error happened on the shutdown of the server: %v", err)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue