diff --git a/README.md b/README.md index 8befa8c..606fd38 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ [![](https://raw.githubusercontent.com/istio/fortio/master/docs/mentioned-badge.svg?sanitize=true)](https://github.com/avelino/awesome-go) -# WebGo v2.3.2 +# WebGo v2.4.0 WebGo is a minimalistic web framework for Go. It gives you the following features. @@ -17,6 +17,7 @@ WebGo is a minimalistic web framework for Go. It gives you the following feature 5. Helper functions 6. HTTPS ready 7. Graceful shutdown +8. Logging interface WebGo's route handlers have the same signature as the standard libraries' HTTP handler. i.e. `http.HandlerFunc` @@ -236,6 +237,40 @@ func main() { ``` +### Logging interface + +Webgo has a singleton, global variable `LOGHANDLER` of type `Logger`. Logger is an interface which +has the following methods: + +```go +type Logger interface { + Debug(data ...interface{}) + Info(data ...interface{}) + Warn(data ...interface{}) + Error(data ...interface{}) + Fatal(data ...interface{}) +} +``` + +The singleton variable is initialized in the package's `init()` function. The default logger which +is initialized in Webgo has uses Go's standard `log` library. + +A custom logger which implements the same interface can be assigned to the singleton to use your own +logger. + +```go + +package main + +import ( + "github.com/bnkamalesh/webgo" +) + +func main() { + webgo.LOGHANDLER = customLogger +} +``` + ## Full sample ```go diff --git a/config.go b/config.go index 3ccd3ef..b608726 100644 --- a/config.go +++ b/config.go @@ -37,17 +37,17 @@ type Config struct { func (cfg *Config) Load(filepath string) { file, err := ioutil.ReadFile(filepath) if err != nil { - errLogger.Fatal(err) + LOGHANDLER.Fatal(err) } err = json.Unmarshal(file, cfg) if err != nil { - errLogger.Fatal(err) + LOGHANDLER.Fatal(err) } err = cfg.Validate() if err != nil { - errLogger.Fatal(ErrInvalidPort) + LOGHANDLER.Fatal(ErrInvalidPort) } } diff --git a/errors.go b/errors.go index cd13197..dc4aabb 100644 --- a/errors.go +++ b/errors.go @@ -11,9 +11,57 @@ var ( ErrInvalidPort = errors.New("Port number not provided or is invalid (should be between 0 - 65535)") ) -var ( - errLogger = log.New(os.Stderr, "Error ", log.LstdFlags|log.Lshortfile) - stdLogger = log.New(os.Stdout, "", log.LstdFlags) - infoLogger = log.New(os.Stdout, "Info ", log.LstdFlags) - warnLogger = log.New(os.Stdout, "Warning ", log.LstdFlags) -) +// Service defines all the logging methods to be implemented +type Logger interface { + Debug(data ...interface{}) + Info(data ...interface{}) + Warn(data ...interface{}) + Error(data ...interface{}) + Fatal(data ...interface{}) +} + +// logHandler has all the log writer handlers +type logHandler struct { + debug *log.Logger + info *log.Logger + warn *log.Logger + err *log.Logger + fatal *log.Logger +} + +// Debug prints log of severity 5 +func (lh *logHandler) Debug(data ...interface{}) { + lh.debug.Println(data...) +} + +// Info prints logs of severity 4 +func (lh *logHandler) Info(data ...interface{}) { + lh.info.Println(data...) +} + +// Warn prints log of severity 3 +func (lh *logHandler) Warn(data ...interface{}) { + lh.warn.Println(data...) +} + +// Error prints log of severity 2 +func (lh *logHandler) Error(data ...interface{}) { + lh.err.Println(data...) +} + +// Fatal prints log of severity 1 +func (lh *logHandler) Fatal(data ...interface{}) { + lh.fatal.Fatalln(data...) +} + +var LOGHANDLER Logger + +func init() { + LOGHANDLER = &logHandler{ + fatal: log.New(os.Stderr, "Fatal ", log.LstdFlags|log.Llongfile), + err: log.New(os.Stderr, "Error ", log.LstdFlags), + warn: log.New(os.Stderr, "Warning ", log.LstdFlags), + info: log.New(os.Stdout, "Info ", log.LstdFlags), + debug: log.New(os.Stdout, "Debug ", log.LstdFlags), + } +} diff --git a/releasenote.md b/releasenote.md index be6f3f9..c626ac3 100644 --- a/releasenote.md +++ b/releasenote.md @@ -1,39 +1,59 @@ -# Release - 09/10/2018 +# Release notes + +## Release - 11/10/2018 + +### v2.4.0 + +1. Updated Readme +2. Updated Logger + - Added a new logging interface +3. Updated tests to cover more code +4. Updated responses to use constants defined in Go's http standard library instead of using +integers for respective HTTP response codes + +## Release - 09/10/2018 + ### v2.3.2 + 1. Updated Readme 2. Updated Middleware - Backward incompatible updates - CORS middleware functions are updated and now accepts list of supported/allowed domains - The middleware functions will default to "*" if no domains are passed to the functions -# Release - 03/05/2018 +## Release - 03/05/2018 + ### v2.2.4 1. 501 response for unsupported HTTP methods -# Release - 12/04/2018 +## Release - 12/04/2018 + ### v2.2.3 1. Fixed the long standing invalid http status code [bug](https://github.com/bnkamalesh/webgo/issues/7) 2. Fixed bug in access-log middleware which caused invalid HTTP status code 3. Updated docs with all latest updates -# Release - 08/04/2018 +## Release - 08/04/2018 + ### v2.2.0 1. Graceful shutdown added 2. Updated readme with details of how to use the shutdown -# Release - 02/04/2018 +## Release - 02/04/2018 + ### v2.1.0 1. Updated Readme to include godoc badge 2. Renamed `middlewares` to `middleware` ### v2.1.1 + 1. Initializing `AppContext` in NewRouter to avoid nil pointer assignment -# Release v2.0.0 - 01/04/2018 +## Release v2.0.0 - 01/04/2018 1. Log levels 1. Error logs are now printed to `os.Stderr` with a prefix `Error` diff --git a/responses.go b/responses.go index 337bd8b..55d3493 100644 --- a/responses.go +++ b/responses.go @@ -82,7 +82,7 @@ func SendResponse(w http.ResponseWriter, data interface{}, rCode int) { In case of encoding error, send "internal server error" after logging the actual error. */ - errLogger.Println(err) + LOGHANDLER.Error(err) R500(w, ErrInternalServer) } } @@ -100,7 +100,7 @@ func SendError(w http.ResponseWriter, data interface{}, rCode int) { In case of encoding error, send "internal server error" after logging the actual error. */ - errLogger.Println(err) + LOGHANDLER.Error(err) R500(w, ErrInternalServer) } } @@ -112,66 +112,69 @@ func Render(w http.ResponseWriter, data interface{}, rCode int, tpl *template.Te w.WriteHeader(rCode) // Rendering an HTML template with appropriate data - tpl.Execute(w, data) + err := tpl.Execute(w, data) + if err != nil { + LOGHANDLER.Error(err.Error()) + } } // Render404 - used to render a 404 page func Render404(w http.ResponseWriter, tpl *template.Template) { Render(w, ErrorData{ - 404, + http.StatusNotFound, "Sorry, the URL you requested was not found on this server... Or you're lost :-/", }, - 404, + http.StatusNotFound, tpl, ) } // R200 - Successful/OK response func R200(w http.ResponseWriter, data interface{}) { - SendResponse(w, data, 200) + SendResponse(w, data, http.StatusOK) } // R201 - New item created func R201(w http.ResponseWriter, data interface{}) { - SendResponse(w, data, 201) + SendResponse(w, data, http.StatusCreated) } // R204 - empty, no content func R204(w http.ResponseWriter) { - SendHeader(w, 204) + SendHeader(w, http.StatusNoContent) } // R302 - Temporary redirect func R302(w http.ResponseWriter, data interface{}) { - SendResponse(w, data, 302) + SendResponse(w, data, http.StatusFound) } // R400 - Invalid request, any incorrect/erraneous value in the request body func R400(w http.ResponseWriter, data interface{}) { - SendError(w, data, 400) + SendError(w, data, http.StatusBadRequest) } // R403 - Unauthorized access func R403(w http.ResponseWriter, data interface{}) { - SendError(w, data, 403) + SendError(w, data, http.StatusForbidden) } // R404 - Resource not found func R404(w http.ResponseWriter, data interface{}) { - SendError(w, data, 404) + SendError(w, data, http.StatusNotFound) } // R406 - Unacceptable header. For any error related to values set in header func R406(w http.ResponseWriter, data interface{}) { - SendError(w, data, 406) + SendError(w, data, http.StatusNotAcceptable) } // R451 - Resource taken down because of a legal request func R451(w http.ResponseWriter, data interface{}) { - SendError(w, data, 451) + SendError(w, data, http.StatusUnavailableForLegalReasons) } // R500 - Internal server error func R500(w http.ResponseWriter, data interface{}) { - SendError(w, data, 500) + SendError(w, data, http.StatusInternalServerError) } diff --git a/responses_test.go b/responses_test.go index ba29e07..ccc25dd 100644 --- a/responses_test.go +++ b/responses_test.go @@ -3,76 +3,77 @@ package webgo import ( "encoding/json" "html/template" + "net/http" "testing" ) func TestResponses(t *testing.T) { _, respRec := setup() R200(respRec, nil) - if respRec.Code != 200 { + if respRec.Code != http.StatusOK { t.Log("Expected response status 200, got", respRec.Code) t.Fail() } _, respRec = setup() R201(respRec, nil) - if respRec.Code != 201 { + if respRec.Code != http.StatusCreated { t.Log("Expected response status 201, got", respRec.Code) t.Fail() } _, respRec = setup() R204(respRec) - if respRec.Code != 204 { + if respRec.Code != http.StatusNoContent { t.Log("Expected response status 204, got", respRec.Code) t.Fail() } _, respRec = setup() R302(respRec, nil) - if respRec.Code != 302 { + if respRec.Code != http.StatusFound { t.Log("Expected response status 302, got", respRec.Code) t.Fail() } _, respRec = setup() R400(respRec, nil) - if respRec.Code != 400 { + if respRec.Code != http.StatusBadRequest { t.Log("Expected response status 400, got", respRec.Code) t.Fail() } _, respRec = setup() R403(respRec, nil) - if respRec.Code != 403 { + if respRec.Code != http.StatusForbidden { t.Log("Expected response status 403, got", respRec.Code) t.Fail() } _, respRec = setup() R404(respRec, nil) - if respRec.Code != 404 { + if respRec.Code != http.StatusNotFound { t.Log("Expected response status 404, got", respRec.Code) t.Fail() } _, respRec = setup() R406(respRec, nil) - if respRec.Code != 406 { + if respRec.Code != http.StatusNotAcceptable { t.Log("Expected response status 406, got", respRec.Code) t.Fail() } _, respRec = setup() R451(respRec, nil) - if respRec.Code != 451 { + if respRec.Code != http.StatusUnavailableForLegalReasons { t.Log("Expected response status 451, got", respRec.Code) t.Fail() } _, respRec = setup() R500(respRec, nil) - if respRec.Code != 500 { + if respRec.Code != http.StatusInternalServerError { t.Log("Expected response status 500, got", respRec.Code) t.Fail() } @@ -90,7 +91,7 @@ func TestInvalidResponses(t *testing.T) { return } - if resp.Status != 500 { + if resp.Status != http.StatusInternalServerError { t.Log("Expected status 500, got:", resp.Status) t.Fail() } @@ -106,7 +107,7 @@ func TestInvalidResponses(t *testing.T) { return } - if resp.Status != 500 { + if resp.Status != http.StatusInternalServerError { t.Log("Expected status 500, got:", resp.Status) t.Fail() } @@ -114,9 +115,9 @@ func TestInvalidResponses(t *testing.T) { func TestSend(t *testing.T) { _, respRec := setup() - Send(respRec, "text/html", "hello", 200) + Send(respRec, "text/html", "hello", http.StatusOK) - if respRec.Code != 200 { + if respRec.Code != http.StatusOK { t.Log("Expected status 200, got", respRec.Code) t.Fail() } @@ -138,7 +139,7 @@ func TestRender(t *testing.T) { return } - Render(respResc, nil, 200, tmpl) + Render(respResc, nil, http.StatusOK, tmpl) str := respResc.Body.String() if str != `hello world` { @@ -167,8 +168,8 @@ func TestRender404(t *testing.T) { func TestSendHeader(t *testing.T) { _, respResc := setup() - SendHeader(respResc, 202) - if respResc.Code != 202 { + SendHeader(respResc, http.StatusAccepted) + if respResc.Code != http.StatusAccepted { t.Log("Expected response code 202, got:", respResc.Code) t.Fail() } diff --git a/router.go b/router.go index 36a6ea1..4bafbb8 100644 --- a/router.go +++ b/router.go @@ -43,7 +43,7 @@ type customResponseWriter struct { // it to the custom response writer func (crw *customResponseWriter) WriteHeader(code int) { if crw.written { - warnLogger.Println(errMultiHeaderWrite) + LOGHANDLER.Warn(errMultiHeaderWrite) return } @@ -55,7 +55,7 @@ func (crw *customResponseWriter) WriteHeader(code int) { // but check if a response was already sent. func (crw *customResponseWriter) Write(body []byte) (int, error) { if crw.written { - warnLogger.Println(errMultiWrite) + LOGHANDLER.Warn(errMultiWrite) return 0, nil } @@ -107,7 +107,7 @@ func (r *Route) computePatternStr(patternString string, hasWildcard bool, key st for idx, k := range r.uriKeys { if key == k { - errLogger.Fatalln(errDuplicateKey, "\nURI: ", r.Pattern, "\nKey:", k, ", Position:", idx+1) + LOGHANDLER.Fatal(errDuplicateKey, "\nURI: ", r.Pattern, "\nKey:", k, ", Position:", idx+1) } } @@ -240,7 +240,7 @@ func (rtr *Router) serve(rw http.ResponseWriter, req *http.Request) { var route *Route ok := false - params := make(map[string]string, 0) + params := make(map[string]string) path := req.URL.EscapedPath() for _, r := range rr { if ok, params = r.matchAndGet(path); ok { @@ -272,7 +272,7 @@ func (rtr *Router) serve(rw http.ResponseWriter, req *http.Request) { ) for _, handler := range route.Handlers { - if crw.written == false { + if !crw.written { // If there has been no write to response writer yet handler(crw, reqwc) } else if route.FallThroughPostResponse { @@ -311,9 +311,10 @@ func NewRouter(cfg *Config, routes []*Route) *Router { deleteHandlers: handlers[http.MethodDelete], NotFound: http.NotFound, - AppContext: make(map[string]interface{}, 0), + AppContext: make(map[string]interface{}), config: cfg, } + // setting the default serve handler r.serveHandler = r.serve @@ -327,14 +328,14 @@ func checkDuplicateRoutes(idx int, route *Route, routes []*Route) { rt := routes[i] if rt.Name == route.Name { - warnLogger.Println("Duplicate route name(\"" + rt.Name + "\") detected. Route name should be unique.") + LOGHANDLER.Warn("Duplicate route name(\"" + rt.Name + "\") detected. Route name should be unique.") } if rt.Method == route.Method { // regex pattern match if ok, _ := rt.matchAndGet(route.Pattern); ok { - warnLogger.Println("Duplicate URI pattern detected.\nPattern: '" + rt.Pattern + "'\nDuplicate pattern: '" + route.Pattern + "'") - infoLogger.Println("Only the first route to match the URI pattern would handle the request") + LOGHANDLER.Warn("Duplicate URI pattern detected.\nPattern: '" + rt.Pattern + "'\nDuplicate pattern: '" + route.Pattern + "'") + LOGHANDLER.Info("Only the first route to match the URI pattern would handle the request") } } } @@ -358,18 +359,18 @@ func httpHandlers(routes []*Route) map[string][]*Route { } if !found { - errLogger.Fatalln("Unsupported HTTP request method provided. Method:", route.Method) + LOGHANDLER.Fatal("Unsupported HTTP request method provided. Method:", route.Method) return nil } if route.Handlers == nil || len(route.Handlers) == 0 { - errLogger.Fatalln("No handlers provided for the route '", route.Pattern, "', method '", route.Method, "'") + LOGHANDLER.Fatal("No handlers provided for the route '", route.Pattern, "', method '", route.Method, "'") return nil } err := route.init() if err != nil { - errLogger.Fatalln("Unsupported URI pattern.", route.Pattern, err) + LOGHANDLER.Fatal("Unsupported URI pattern.", route.Pattern, err) return nil } diff --git a/webgo.go b/webgo.go index fde7a14..f7c0603 100644 --- a/webgo.go +++ b/webgo.go @@ -41,11 +41,11 @@ func Context(r *http.Request) *WC { func (router *Router) StartHTTPS() { cfg := router.config if cfg.CertFile == "" { - errLogger.Fatalln("No certificate provided for HTTPS") + LOGHANDLER.Fatal("No certificate provided for HTTPS") } if cfg.KeyFile == "" { - errLogger.Fatalln("No key file provided for HTTPS") + LOGHANDLER.Fatal("No key file provided for HTTPS") } host := cfg.Host @@ -63,10 +63,10 @@ func (router *Router) StartHTTPS() { }, } - infoLogger.Println("HTTPS server, listening on", host) + LOGHANDLER.Info("HTTPS server, listening on", host) err := router.httpsServer.ListenAndServeTLS(cfg.CertFile, cfg.KeyFile) if err != nil && err != http.ErrServerClosed { - errLogger.Println("HTTPS server exited with error:", err.Error()) + LOGHANDLER.Error("HTTPS server exited with error:", err.Error()) } } @@ -85,10 +85,10 @@ func (router *Router) Start() { ReadTimeout: cfg.ReadTimeout, WriteTimeout: cfg.WriteTimeout, } - infoLogger.Println("HTTP server, listening on", host) + LOGHANDLER.Info("HTTP server, listening on", host) err := router.httpServer.ListenAndServe() if err != nil && err != http.ErrServerClosed { - errLogger.Println("HTTP server exited with error:", err.Error()) + LOGHANDLER.Error("HTTP server exited with error:", err.Error()) } } @@ -104,7 +104,7 @@ func (router *Router) Shutdown() error { err := router.httpServer.Shutdown(ctx) if err != nil { - errLogger.Println(err) + LOGHANDLER.Error(err) } return err } @@ -121,7 +121,7 @@ func (router *Router) ShutdownHTTPS() error { err := router.httpsServer.Shutdown(ctx) if err != nil && err != http.ErrServerClosed { - errLogger.Println(err) + LOGHANDLER.Error(err) } return err } diff --git a/webgo_test.go b/webgo_test.go index 5a409bf..64f2922 100644 --- a/webgo_test.go +++ b/webgo_test.go @@ -92,14 +92,30 @@ func setup() (*Router, *httptest.ResponseRecorder) { return router, httptest.NewRecorder() } +func TestInvalidHTTPMethod(t *testing.T) { + router, respRec := setup() + + for _, url := range GETAPI { + req, err := http.NewRequest("ABC", url, bytes.NewBuffer(nil)) + if err != nil { + t.Fatal(err, url) + continue + } + + router.ServeHTTP(respRec, req) + if respRec.Code != http.StatusNotImplemented { + t.Fatalf(`Expected response HTTP status code %d, received %d`, http.StatusNotImplemented, respRec.Code) + } + } +} + func TestGet(t *testing.T) { router, respRec := setup() for _, url := range GETAPI { req, err := http.NewRequest(http.MethodGet, url, bytes.NewBuffer(nil)) if err != nil { - t.Log(err, url) - t.Fail() + t.Fatal(err, url) continue } @@ -109,24 +125,20 @@ func TestGet(t *testing.T) { err = json.NewDecoder(respRec.Body).Decode(&resp) if err != nil { - t.Log(err) - t.Fail() + t.Fatal(err) continue } if resp.Data["method"] != http.MethodGet { - t.Log("URL:", url, "response method:", resp.Data["method"], " required method:", http.MethodGet) - t.Fail() + t.Fatal("URL:", url, "response method:", resp.Data["method"], " required method:", http.MethodGet) } if resp.Data["p1"] != p1 { - t.Log("p1:", resp.Data["p1"]) - t.Fail() + t.Fatal("p1:", resp.Data["p1"]) } if resp.Data["p2"] != p2 { - t.Log("p2:", resp.Data["p2"]) - t.Fail() + t.Fatal("p2:", resp.Data["p2"]) } } } @@ -137,20 +149,20 @@ func TestMiddleware(t *testing.T) { url := baseapi + "/" req, err := http.NewRequest(http.MethodGet, url, bytes.NewBuffer(nil)) if err != nil { - t.Log(err, url) - t.Fail() + t.Fatal(err, url) + } router.ServeHTTP(respRec, req) - if respRec.Code != 200 { - t.Log(err, respRec.Code, url) - t.Fail() + if respRec.Code != http.StatusOK { + t.Fatal(err, respRec.Code, url) + } v := respRec.Header().Get("k1") if respRec.Header().Get("k1") != "v1" { - t.Log("Expected response header value `v1` for key `k1`, received", v) - t.Fail() + t.Fatal("Expected response header value `v1` for key `k1`, received", v) + } } func TestGetPostResponse(t *testing.T) { @@ -158,14 +170,14 @@ func TestGetPostResponse(t *testing.T) { url := baseapi + "/" req, err := http.NewRequest(http.MethodGet, url, bytes.NewBuffer(nil)) if err != nil { - t.Log(err, url) - t.Fail() + t.Fatal(err, url) + } router.ServeHTTP(respRec, req) - if respRec.Code != 200 { - t.Log(err, respRec.Code, url) - t.Fail() + if respRec.Code != http.StatusOK { + t.Fatal(err, respRec.Code, url) + } } func TestGet404(t *testing.T) { @@ -173,15 +185,15 @@ func TestGet404(t *testing.T) { url := baseapi + "/random" req, err := http.NewRequest(http.MethodGet, url, bytes.NewBuffer(nil)) if err != nil { - t.Log(err, url) - t.Fail() + t.Fatal(err, url) + } router.ServeHTTP(respRec, req) if respRec.Code != 404 { - t.Log(err) - t.Fail() + t.Fatal(err) + } } func TestHead(t *testing.T) { @@ -190,8 +202,8 @@ func TestHead(t *testing.T) { for _, url := range GETAPI { req, err := http.NewRequest(http.MethodHead, url, bytes.NewBuffer(nil)) if err != nil { - t.Log(err, url) - t.Fail() + t.Fatal(err, url) + continue } @@ -201,24 +213,24 @@ func TestHead(t *testing.T) { err = json.NewDecoder(respRec.Body).Decode(&resp) if err != nil { - t.Log(err) - t.Fail() + t.Fatal(err) + continue } if resp.Data["method"] != http.MethodHead { - t.Log("URL:", url, "response method:", resp.Data["method"], " required method:", http.MethodGet) - t.Fail() + t.Fatal("URL:", url, "response method:", resp.Data["method"], " required method:", http.MethodGet) + } if resp.Data["p1"] != p1 { - t.Log("p1:", resp.Data["p1"]) - t.Fail() + t.Fatal("p1:", resp.Data["p1"]) + } if resp.Data["p2"] != p2 { - t.Log("p2:", resp.Data["p2"]) - t.Fail() + t.Fatal("p2:", resp.Data["p2"]) + } } } @@ -230,37 +242,37 @@ func TestPost(t *testing.T) { for _, url := range POSTAPI { req, err := http.NewRequest(http.MethodPost, url, bytes.NewBuffer(payload)) if err != nil { - t.Log(err, url) - t.Fail() + t.Fatal(err, url) + continue } router.ServeHTTP(respRec, req) resp := response{} err = json.NewDecoder(respRec.Body).Decode(&resp) if err != nil { - t.Log(err) - t.Fail() + t.Fatal(err) + continue } if resp.Data["method"] != http.MethodPost { - t.Log("response method:", resp.Data["method"], " required method:", http.MethodPost) - t.Fail() + t.Fatal("response method:", resp.Data["method"], " required method:", http.MethodPost) + } if resp.Data["p1"] != p1 { - t.Log("p1:", resp.Data["p1"]) - t.Fail() + t.Fatal("p1:", resp.Data["p1"]) + } if resp.Data["p2"] != p2 { - t.Log("p2:", resp.Data["p2"]) - t.Fail() + t.Fatal("p2:", resp.Data["p2"]) + } if resp.Data["payload"] != string(payload) { - t.Log("payload:", resp.Data["payload"]) - t.Fail() + t.Fatal("payload:", resp.Data["payload"]) + } } } @@ -272,37 +284,37 @@ func TestPut(t *testing.T) { req, err := http.NewRequest(http.MethodPut, url, bytes.NewBuffer(payload)) if err != nil { - t.Log(err, url) - t.Fail() + t.Fatal(err, url) + continue } router.ServeHTTP(respRec, req) resp := response{} err = json.NewDecoder(respRec.Body).Decode(&resp) if err != nil { - t.Log(err) - t.Fail() + t.Fatal(err) + continue } if resp.Data["method"] != http.MethodPut { - t.Log("response method:", resp.Data["method"], " required method:", http.MethodPut) - t.Fail() + t.Fatal("response method:", resp.Data["method"], " required method:", http.MethodPut) + } if resp.Data["p1"] != p1 { - t.Log("p1:", resp.Data["p1"]) - t.Fail() + t.Fatal("p1:", resp.Data["p1"]) + } if resp.Data["p2"] != p2 { - t.Log("p2:", resp.Data["p2"]) - t.Fail() + t.Fatal("p2:", resp.Data["p2"]) + } if resp.Data["payload"] != string(payload) { - t.Log("payload:", resp.Data["payload"]) - t.Fail() + t.Fatal("payload:", resp.Data["payload"]) + } } } @@ -313,8 +325,8 @@ func TestPatch(t *testing.T) { for _, url := range PATCHAPI { req, err := http.NewRequest(http.MethodPatch, url, bytes.NewBuffer(payload)) if err != nil { - t.Log(err, url) - t.Fail() + t.Fatal(err, url) + continue } @@ -322,29 +334,29 @@ func TestPatch(t *testing.T) { router.ServeHTTP(respRec, req) err = json.NewDecoder(respRec.Body).Decode(&resp) if err != nil { - t.Log(err) - t.Fail() + t.Fatal(err) + continue } if resp.Data["method"] != http.MethodPatch { - t.Log("response method:", resp.Data["method"], " required method:", http.MethodPatch) - t.Fail() + t.Fatal("response method:", resp.Data["method"], " required method:", http.MethodPatch) + } if resp.Data["p1"] != p1 { - t.Log("p1:", resp.Data["p1"]) - t.Fail() + t.Fatal("p1:", resp.Data["p1"]) + } if resp.Data["p2"] != p2 { - t.Log("p2:", resp.Data["p2"]) - t.Fail() + t.Fatal("p2:", resp.Data["p2"]) + } if resp.Data["payload"] != string(payload) { - t.Log("payload:", resp.Data["payload"]) - t.Fail() + t.Fatal("payload:", resp.Data["payload"]) + } } } @@ -355,8 +367,8 @@ func TestDelete(t *testing.T) { for _, url := range DELETEAPI { req, err := http.NewRequest(http.MethodDelete, url, bytes.NewBuffer(payload)) if err != nil { - t.Log(err, url) - t.Fail() + t.Fatal(err, url) + continue } @@ -364,29 +376,29 @@ func TestDelete(t *testing.T) { router.ServeHTTP(respRec, req) err = json.NewDecoder(respRec.Body).Decode(&resp) if err != nil { - t.Log(err) - t.Fail() + t.Fatal(err) + continue } if resp.Data["method"] != http.MethodDelete { - t.Log("response method:", resp.Data["method"], " required method:", http.MethodDelete) - t.Fail() + t.Fatal("response method:", resp.Data["method"], " required method:", http.MethodDelete) + } if resp.Data["p1"] != p1 { - t.Log("p1:", resp.Data["p1"]) - t.Fail() + t.Fatal("p1:", resp.Data["p1"]) + } if resp.Data["p2"] != p2 { - t.Log("p2:", resp.Data["p2"]) - t.Fail() + t.Fatal("p2:", resp.Data["p2"]) + } if resp.Data["payload"] != string(payload) { - t.Log("payload:", resp.Data["payload"]) - t.Fail() + t.Fatal("payload:", resp.Data["payload"]) + } } } @@ -398,8 +410,8 @@ func TestOptions(t *testing.T) { for _, url := range OPTIONSAPI { req, err := http.NewRequest(http.MethodOptions, url, bytes.NewBuffer(payload)) if err != nil { - t.Log(err, url) - t.Fail() + t.Fatal(err, url) + continue } @@ -407,29 +419,29 @@ func TestOptions(t *testing.T) { router.ServeHTTP(respRec, req) err = json.NewDecoder(respRec.Body).Decode(&resp) if err != nil { - t.Log(err) - t.Fail() + t.Fatal(err) + continue } if resp.Data["method"] != http.MethodOptions { - t.Log("response method:", resp.Data["method"], " required method:", http.MethodOptions) - t.Fail() + t.Fatal("response method:", resp.Data["method"], " required method:", http.MethodOptions) + } if resp.Data["p1"] != p1 { - t.Log("p1:", resp.Data["p1"]) - t.Fail() + t.Fatal("p1:", resp.Data["p1"]) + } if resp.Data["p2"] != p2 { - t.Log("p2:", resp.Data["p2"]) - t.Fail() + t.Fatal("p2:", resp.Data["p2"]) + } if resp.Data["payload"] != string(payload) { - t.Log("payload:", resp.Data["payload"]) - t.Fail() + t.Fatal("payload:", resp.Data["payload"]) + } } } @@ -439,8 +451,8 @@ func TestAppContext(t *testing.T) { for _, url := range GETAppContextAPI { req, err := http.NewRequest(http.MethodGet, url, bytes.NewBuffer(nil)) if err != nil { - t.Log(err, url) - t.Fail() + t.Fatal(err, url) + continue } @@ -448,14 +460,14 @@ func TestAppContext(t *testing.T) { router.ServeHTTP(respRec, req) err = json.NewDecoder(respRec.Body).Decode(&resp) if err != nil { - t.Log(err) - t.Fail() + t.Fatal(err) + continue } if resp.Data["Name"] != "WebGo" { - t.Log("Invalid App context config received") - t.Fail() + t.Fatal("Invalid App context config received") + } } @@ -467,8 +479,8 @@ func TestStart(t *testing.T) { time.Sleep(time.Second * 5) err := router.Shutdown() if err != nil { - t.Log(err) - t.Fail() + t.Fatal(err) + } } func TestStartHTTPS(t *testing.T) { @@ -477,50 +489,10 @@ func TestStartHTTPS(t *testing.T) { time.Sleep(time.Second * 5) err := router.ShutdownHTTPS() if err != nil { - t.Log(err) - t.Fail() - } -} - -/* -func BenchmarkGetWithoutURIParams(b *testing.B) { - var err error - var url = BenchAPIs["GETNOPARAM"] - for i := 0; i < b.N; i++ { - _, err = GetAnyJSON(url) - if err != nil { - b.Error(err) - return - } - } -} + t.Fatal(err) -func BenchmarkGetWithURIParams(b *testing.B) { - var err error - var url = BenchAPIs["GETWITHPARAM"] - for i := 0; i < b.N; i++ { - _, err = GetAnyJSON(url) - if err != nil { - b.Error(err) - return - } - } -} - -func BenchmarkPOSTWithURIParams(b *testing.B) { - var err error - var url = BenchAPIs["POSTWITHPARAM"] - var payload = []byte(`{"payload": "nothing"}`) - - for i := 0; i < b.N; i++ { - _, err = Post(url, payload) - if err != nil { - b.Error(err) - return - } } } -*/ func dummy(w http.ResponseWriter, r *http.Request) {