mirror of https://github.com/gin-gonic/gin.git
feat: replace debug log with fmt package. (#1560)
This commit is contained in:
parent
b27b7026c7
commit
07f1bf0e63
|
@ -784,14 +784,14 @@ func TestContextRenderHTML2(t *testing.T) {
|
||||||
router.addRoute("GET", "/", HandlersChain{func(_ *Context) {}})
|
router.addRoute("GET", "/", HandlersChain{func(_ *Context) {}})
|
||||||
assert.Len(t, router.trees, 1)
|
assert.Len(t, router.trees, 1)
|
||||||
|
|
||||||
var b bytes.Buffer
|
|
||||||
setup(&b)
|
|
||||||
defer teardown()
|
|
||||||
|
|
||||||
templ := template.Must(template.New("t").Parse(`Hello {{.name}}`))
|
templ := template.Must(template.New("t").Parse(`Hello {{.name}}`))
|
||||||
|
re := captureOutput(func() {
|
||||||
|
SetMode(DebugMode)
|
||||||
router.SetHTMLTemplate(templ)
|
router.SetHTMLTemplate(templ)
|
||||||
|
SetMode(TestMode)
|
||||||
|
})
|
||||||
|
|
||||||
assert.Equal(t, "[GIN-debug] [WARNING] Since SetHTMLTemplate() is NOT thread-safe. It should only be called\nat initialization. ie. before any route is registered or the router is listening in a socket:\n\n\trouter := gin.Default()\n\trouter.SetHTMLTemplate(template) // << good place\n\n", b.String())
|
assert.Equal(t, "[GIN-debug] [WARNING] Since SetHTMLTemplate() is NOT thread-safe. It should only be called\nat initialization. ie. before any route is registered or the router is listening in a socket:\n\n\trouter := gin.Default()\n\trouter.SetHTMLTemplate(template) // << good place\n\n", re)
|
||||||
|
|
||||||
c.HTML(http.StatusCreated, "t", H{"name": "alexandernyquist"})
|
c.HTML(http.StatusCreated, "t", H{"name": "alexandernyquist"})
|
||||||
|
|
||||||
|
|
8
debug.go
8
debug.go
|
@ -6,14 +6,10 @@ package gin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"fmt"
|
||||||
"html/template"
|
"html/template"
|
||||||
"log"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
|
||||||
log.SetFlags(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsDebugging returns true if the framework is running in debug mode.
|
// IsDebugging returns true if the framework is running in debug mode.
|
||||||
// Use SetMode(gin.ReleaseMode) to disable debug mode.
|
// Use SetMode(gin.ReleaseMode) to disable debug mode.
|
||||||
func IsDebugging() bool {
|
func IsDebugging() bool {
|
||||||
|
@ -48,7 +44,7 @@ func debugPrintLoadTemplate(tmpl *template.Template) {
|
||||||
|
|
||||||
func debugPrint(format string, values ...interface{}) {
|
func debugPrint(format string, values ...interface{}) {
|
||||||
if IsDebugging() {
|
if IsDebugging() {
|
||||||
log.Printf("[GIN-debug] "+format, values...)
|
fmt.Printf("[GIN-debug] "+format, values...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
110
debug_test.go
110
debug_test.go
|
@ -11,6 +11,7 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
@ -30,86 +31,101 @@ func TestIsDebugging(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDebugPrint(t *testing.T) {
|
func TestDebugPrint(t *testing.T) {
|
||||||
var w bytes.Buffer
|
re := captureOutput(func() {
|
||||||
setup(&w)
|
SetMode(DebugMode)
|
||||||
defer teardown()
|
|
||||||
|
|
||||||
SetMode(ReleaseMode)
|
SetMode(ReleaseMode)
|
||||||
debugPrint("DEBUG this!")
|
debugPrint("DEBUG this!")
|
||||||
SetMode(TestMode)
|
SetMode(TestMode)
|
||||||
debugPrint("DEBUG this!")
|
debugPrint("DEBUG this!")
|
||||||
assert.Empty(t, w.String())
|
|
||||||
|
|
||||||
SetMode(DebugMode)
|
SetMode(DebugMode)
|
||||||
debugPrint("these are %d %s\n", 2, "error messages")
|
debugPrint("these are %d %s\n", 2, "error messages")
|
||||||
assert.Equal(t, "[GIN-debug] these are 2 error messages\n", w.String())
|
SetMode(TestMode)
|
||||||
|
})
|
||||||
|
assert.Equal(t, "[GIN-debug] these are 2 error messages\n", re)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDebugPrintError(t *testing.T) {
|
func TestDebugPrintError(t *testing.T) {
|
||||||
var w bytes.Buffer
|
re := captureOutput(func() {
|
||||||
setup(&w)
|
|
||||||
defer teardown()
|
|
||||||
|
|
||||||
SetMode(DebugMode)
|
SetMode(DebugMode)
|
||||||
debugPrintError(nil)
|
debugPrintError(nil)
|
||||||
assert.Empty(t, w.String())
|
|
||||||
|
|
||||||
debugPrintError(errors.New("this is an error"))
|
debugPrintError(errors.New("this is an error"))
|
||||||
assert.Equal(t, "[GIN-debug] [ERROR] this is an error\n", w.String())
|
SetMode(TestMode)
|
||||||
|
})
|
||||||
|
assert.Equal(t, "[GIN-debug] [ERROR] this is an error\n", re)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDebugPrintRoutes(t *testing.T) {
|
func TestDebugPrintRoutes(t *testing.T) {
|
||||||
var w bytes.Buffer
|
re := captureOutput(func() {
|
||||||
setup(&w)
|
SetMode(DebugMode)
|
||||||
defer teardown()
|
|
||||||
|
|
||||||
debugPrintRoute("GET", "/path/to/route/:param", HandlersChain{func(c *Context) {}, handlerNameTest})
|
debugPrintRoute("GET", "/path/to/route/:param", HandlersChain{func(c *Context) {}, handlerNameTest})
|
||||||
assert.Regexp(t, `^\[GIN-debug\] GET /path/to/route/:param --> (.*/vendor/)?github.com/gin-gonic/gin.handlerNameTest \(2 handlers\)\n$`, w.String())
|
SetMode(TestMode)
|
||||||
|
})
|
||||||
|
assert.Regexp(t, `^\[GIN-debug\] GET /path/to/route/:param --> (.*/vendor/)?github.com/gin-gonic/gin.handlerNameTest \(2 handlers\)\n$`, re)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDebugPrintLoadTemplate(t *testing.T) {
|
func TestDebugPrintLoadTemplate(t *testing.T) {
|
||||||
var w bytes.Buffer
|
re := captureOutput(func() {
|
||||||
setup(&w)
|
SetMode(DebugMode)
|
||||||
defer teardown()
|
|
||||||
|
|
||||||
templ := template.Must(template.New("").Delims("{[{", "}]}").ParseGlob("./testdata/template/hello.tmpl"))
|
templ := template.Must(template.New("").Delims("{[{", "}]}").ParseGlob("./testdata/template/hello.tmpl"))
|
||||||
debugPrintLoadTemplate(templ)
|
debugPrintLoadTemplate(templ)
|
||||||
assert.Regexp(t, `^\[GIN-debug\] Loaded HTML Templates \(2\): \n(\t- \n|\t- hello\.tmpl\n){2}\n`, w.String())
|
SetMode(TestMode)
|
||||||
|
})
|
||||||
|
assert.Regexp(t, `^\[GIN-debug\] Loaded HTML Templates \(2\): \n(\t- \n|\t- hello\.tmpl\n){2}\n`, re)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDebugPrintWARNINGSetHTMLTemplate(t *testing.T) {
|
func TestDebugPrintWARNINGSetHTMLTemplate(t *testing.T) {
|
||||||
var w bytes.Buffer
|
re := captureOutput(func() {
|
||||||
setup(&w)
|
SetMode(DebugMode)
|
||||||
defer teardown()
|
|
||||||
|
|
||||||
debugPrintWARNINGSetHTMLTemplate()
|
debugPrintWARNINGSetHTMLTemplate()
|
||||||
assert.Equal(t, "[GIN-debug] [WARNING] Since SetHTMLTemplate() is NOT thread-safe. It should only be called\nat initialization. ie. before any route is registered or the router is listening in a socket:\n\n\trouter := gin.Default()\n\trouter.SetHTMLTemplate(template) // << good place\n\n", w.String())
|
SetMode(TestMode)
|
||||||
|
})
|
||||||
|
assert.Equal(t, "[GIN-debug] [WARNING] Since SetHTMLTemplate() is NOT thread-safe. It should only be called\nat initialization. ie. before any route is registered or the router is listening in a socket:\n\n\trouter := gin.Default()\n\trouter.SetHTMLTemplate(template) // << good place\n\n", re)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDebugPrintWARNINGDefault(t *testing.T) {
|
func TestDebugPrintWARNINGDefault(t *testing.T) {
|
||||||
var w bytes.Buffer
|
re := captureOutput(func() {
|
||||||
setup(&w)
|
SetMode(DebugMode)
|
||||||
defer teardown()
|
|
||||||
|
|
||||||
debugPrintWARNINGDefault()
|
debugPrintWARNINGDefault()
|
||||||
assert.Equal(t, "[GIN-debug] [WARNING] Now Gin requires Go 1.6 or later and Go 1.7 will be required soon.\n\n[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.\n\n", w.String())
|
SetMode(TestMode)
|
||||||
|
})
|
||||||
|
assert.Equal(t, "[GIN-debug] [WARNING] Now Gin requires Go 1.6 or later and Go 1.7 will be required soon.\n\n[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.\n\n", re)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDebugPrintWARNINGNew(t *testing.T) {
|
func TestDebugPrintWARNINGNew(t *testing.T) {
|
||||||
var w bytes.Buffer
|
re := captureOutput(func() {
|
||||||
setup(&w)
|
|
||||||
defer teardown()
|
|
||||||
|
|
||||||
debugPrintWARNINGNew()
|
|
||||||
assert.Equal(t, "[GIN-debug] [WARNING] Running in \"debug\" mode. Switch to \"release\" mode in production.\n - using env:\texport GIN_MODE=release\n - using code:\tgin.SetMode(gin.ReleaseMode)\n\n", w.String())
|
|
||||||
}
|
|
||||||
|
|
||||||
func setup(w io.Writer) {
|
|
||||||
SetMode(DebugMode)
|
SetMode(DebugMode)
|
||||||
log.SetOutput(w)
|
debugPrintWARNINGNew()
|
||||||
|
SetMode(TestMode)
|
||||||
|
})
|
||||||
|
assert.Equal(t, "[GIN-debug] [WARNING] Running in \"debug\" mode. Switch to \"release\" mode in production.\n - using env:\texport GIN_MODE=release\n - using code:\tgin.SetMode(gin.ReleaseMode)\n\n", re)
|
||||||
}
|
}
|
||||||
|
|
||||||
func teardown() {
|
func captureOutput(f func()) string {
|
||||||
SetMode(TestMode)
|
reader, writer, err := os.Pipe()
|
||||||
log.SetOutput(os.Stdout)
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
stdout := os.Stdout
|
||||||
|
stderr := os.Stderr
|
||||||
|
defer func() {
|
||||||
|
os.Stdout = stdout
|
||||||
|
os.Stderr = stderr
|
||||||
|
log.SetOutput(os.Stderr)
|
||||||
|
}()
|
||||||
|
os.Stdout = writer
|
||||||
|
os.Stderr = writer
|
||||||
|
log.SetOutput(writer)
|
||||||
|
out := make(chan string)
|
||||||
|
wg := new(sync.WaitGroup)
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
wg.Done()
|
||||||
|
io.Copy(&buf, reader)
|
||||||
|
out <- buf.String()
|
||||||
|
}()
|
||||||
|
wg.Wait()
|
||||||
|
f()
|
||||||
|
writer.Close()
|
||||||
|
return <-out
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue