From 06788c3e125565dc7dcb73655d40f0bb0754d846 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mike=20Schw=C3=B6rer?= Date: Fri, 9 Dec 2022 00:40:50 +0100 Subject: [PATCH] TestData-Factory [WIP] --- server/common/ginext/gin.go | 10 +++++++- server/config.go | 10 ++++---- server/test/util/factory.go | 14 +++++++++++ server/test/util/init.go | 18 ++++++++++---- server/test/util/log.go | 47 +++++++++++++++++++++++++++++++++++ server/test/util/logbuffer.go | 38 ++++++++++++++++++++++++++++ server/test/util/requests.go | 30 +++++++++++----------- server/test/util/webserver.go | 3 +-- 8 files changed, 142 insertions(+), 28 deletions(-) create mode 100644 server/test/util/log.go create mode 100644 server/test/util/logbuffer.go diff --git a/server/common/ginext/gin.go b/server/common/ginext/gin.go index 3fc7f2b..8089df1 100644 --- a/server/common/ginext/gin.go +++ b/server/common/ginext/gin.go @@ -5,6 +5,8 @@ import ( "github.com/gin-gonic/gin" ) +var SuppressGinLogs = false + func NewEngine(cfg scn.Config) *gin.Engine { engine := gin.New() @@ -14,7 +16,13 @@ func NewEngine(cfg scn.Config) *gin.Engine { engine.Use(CorsMiddleware()) if cfg.GinDebug { - engine.Use(gin.Logger()) + ginlogger := gin.Logger() + engine.Use(func(context *gin.Context) { + if SuppressGinLogs { + return + } + ginlogger(context) + }) } return engine diff --git a/server/config.go b/server/config.go index d92aeb0..fcb6516 100644 --- a/server/config.go +++ b/server/config.go @@ -56,7 +56,7 @@ var configLocHost = func() Config { DBFile: ".run-data/db.sqlite3", DBJournal: "WAL", DBTimeout: 5 * time.Second, - DBCheckForeignKeys: true, + DBCheckForeignKeys: false, DBMaxOpenConns: 5, DBMaxIdleConns: 5, DBConnMaxLifetime: 60 * time.Minute, @@ -90,7 +90,7 @@ var configLocDocker = func() Config { DBFile: "/data/scn_docker.sqlite3", DBJournal: "WAL", DBTimeout: 5 * time.Second, - DBCheckForeignKeys: true, + DBCheckForeignKeys: false, DBMaxOpenConns: 5, DBMaxIdleConns: 5, DBConnMaxLifetime: 60 * time.Minute, @@ -124,7 +124,7 @@ var configDev = func() Config { DBFile: "/data/scn.sqlite3", DBJournal: "WAL", DBTimeout: 5 * time.Second, - DBCheckForeignKeys: true, + DBCheckForeignKeys: false, DBMaxOpenConns: 5, DBMaxIdleConns: 5, DBConnMaxLifetime: 60 * time.Minute, @@ -158,7 +158,7 @@ var configStag = func() Config { DBFile: "/data/scn.sqlite3", DBJournal: "WAL", DBTimeout: 5 * time.Second, - DBCheckForeignKeys: true, + DBCheckForeignKeys: false, DBMaxOpenConns: 5, DBMaxIdleConns: 5, DBConnMaxLifetime: 60 * time.Minute, @@ -192,7 +192,7 @@ var configProd = func() Config { DBFile: "/data/scn.sqlite3", DBJournal: "WAL", DBTimeout: 5 * time.Second, - DBCheckForeignKeys: true, + DBCheckForeignKeys: false, DBMaxOpenConns: 5, DBMaxIdleConns: 5, DBConnMaxLifetime: 60 * time.Minute, diff --git a/server/test/util/factory.go b/server/test/util/factory.go index ba4501c..82b9e67 100644 --- a/server/test/util/factory.go +++ b/server/test/util/factory.go @@ -4,6 +4,7 @@ import ( "blackforestbytes.com/simplecloudnotifier/logic" "fmt" "github.com/gin-gonic/gin" + "github.com/rs/zerolog/log" "gogs.mikescher.com/BlackForestBytes/goext/timeext" "gopkg.in/loremipsum.v1" "testing" @@ -266,6 +267,17 @@ var messageExamples = []msgex{ } func InitDefaultData(t *testing.T, ws *logic.Application) { + + // set logger to buffer, only output if error occured + success := false + SetBufLogger() + defer func() { + ClearBufLogger(!success) + if success { + log.Info().Msgf("Succesfully initialized default data (%d messages, %d users)", len(messageExamples), len(userExamples)) + } + }() + baseUrl := "http://127.0.0.1:" + ws.Port users := make([]userdat, 0, len(userExamples)) @@ -347,6 +359,8 @@ func InitDefaultData(t *testing.T, ws *logic.Application) { RequestPost[gin.H](t, baseUrl, "/", body) } + + success = true } func lipsum(seed int64, paracount int) string { diff --git a/server/test/util/init.go b/server/test/util/init.go index 3e06010..7721168 100644 --- a/server/test/util/init.go +++ b/server/test/util/init.go @@ -4,24 +4,32 @@ import ( "github.com/gin-gonic/gin" "github.com/rs/zerolog" "github.com/rs/zerolog/log" + "io" "os" ) func InitTests() { - cw := zerolog.ConsoleWriter{ + log.Logger = createLogger(createConsoleWriter()) + + gin.SetMode(gin.TestMode) + zerolog.SetGlobalLevel(zerolog.DebugLevel) +} + +func createConsoleWriter() *zerolog.ConsoleWriter { + return &zerolog.ConsoleWriter{ Out: os.Stdout, TimeFormat: "2006-01-02 15:04:05.000 Z07:00", } +} +func createLogger(cw io.Writer) zerolog.Logger { zerolog.TimeFieldFormat = zerolog.TimeFormatUnixMs + multi := zerolog.MultiLevelWriter(cw) logger := zerolog.New(multi).With(). Timestamp(). Caller(). Logger() - log.Logger = logger - - gin.SetMode(gin.TestMode) - zerolog.SetGlobalLevel(zerolog.DebugLevel) + return logger } diff --git a/server/test/util/log.go b/server/test/util/log.go new file mode 100644 index 0000000..68faa55 --- /dev/null +++ b/server/test/util/log.go @@ -0,0 +1,47 @@ +package util + +import ( + "blackforestbytes.com/simplecloudnotifier/common/ginext" + "fmt" + "github.com/gin-gonic/gin" + "github.com/rs/zerolog/log" +) + +var buflogger *BufferWriter = nil + +func SetBufLogger() { + buflogger = &BufferWriter{cw: createConsoleWriter()} + log.Logger = createLogger(buflogger) + gin.SetMode(gin.ReleaseMode) + ginext.SuppressGinLogs = true +} + +func ClearBufLogger(dump bool) { + size := len(buflogger.buffer) + if dump { + buflogger.Dump() + } + log.Logger = createLogger(createConsoleWriter()) + buflogger = nil + gin.SetMode(gin.TestMode) + ginext.SuppressGinLogs = false + if !dump { + log.Info().Msgf("Suppressed %d logmessages / printf-statements", size) + } +} + +func TPrintf(format string, a ...any) { + if buflogger != nil { + buflogger.Printf(format, a...) + } else { + fmt.Printf(format, a...) + } +} + +func TPrintln(a ...any) { + if buflogger != nil { + buflogger.Println(a...) + } else { + fmt.Println(a...) + } +} diff --git a/server/test/util/logbuffer.go b/server/test/util/logbuffer.go new file mode 100644 index 0000000..0ef7963 --- /dev/null +++ b/server/test/util/logbuffer.go @@ -0,0 +1,38 @@ +package util + +import ( + "fmt" + "github.com/rs/zerolog" +) + +type BufferWriter struct { + cw *zerolog.ConsoleWriter + + buffer []func(cw *zerolog.ConsoleWriter) +} + +func (b *BufferWriter) Write(p []byte) (n int, err error) { + b.buffer = append(b.buffer, func(cw *zerolog.ConsoleWriter) { + _, _ = cw.Write(p) + }) + return len(p), nil +} + +func (b *BufferWriter) Dump() { + for _, v := range b.buffer { + v(b.cw) + } + b.buffer = nil +} + +func (b *BufferWriter) Println(a ...any) { + b.buffer = append(b.buffer, func(cw *zerolog.ConsoleWriter) { + fmt.Println(a...) + }) +} + +func (b *BufferWriter) Printf(format string, a ...any) { + b.buffer = append(b.buffer, func(cw *zerolog.ConsoleWriter) { + fmt.Printf(format, a...) + }) +} diff --git a/server/test/util/requests.go b/server/test/util/requests.go index 3f33465..b608de0 100644 --- a/server/test/util/requests.go +++ b/server/test/util/requests.go @@ -89,7 +89,7 @@ func RequestAuthDeleteShouldFail(t *testing.T, akey string, baseURL string, urlS func RequestAny[TResult any](t *testing.T, akey string, method string, baseURL string, urlSuffix string, body any) TResult { client := http.Client{} - fmt.Printf("[-> REQUEST] (%s) %s%s [%s] [%s]\n", method, baseURL, urlSuffix, langext.Conditional(akey == "", "NO AUTH", "AUTH"), langext.Conditional(body == nil, "NO BODY", "BODY")) + TPrintf("[-> REQUEST] (%s) %s%s [%s] [%s]\n", method, baseURL, urlSuffix, langext.Conditional(akey == "", "NO AUTH", "AUTH"), langext.Conditional(body == nil, "NO BODY", "BODY")) bytesbody := make([]byte, 0) contentType := "" @@ -144,12 +144,12 @@ func RequestAny[TResult any](t *testing.T, akey string, method string, baseURL s TestFailErr(t, err) } - fmt.Println("") - fmt.Printf("---------------- RESPONSE (%d) ----------------\n", resp.StatusCode) - fmt.Println(langext.TryPrettyPrintJson(string(respBodyBin))) + TPrintln("") + TPrintf("---------------- RESPONSE (%d) ----------------\n", resp.StatusCode) + TPrintln(langext.TryPrettyPrintJson(string(respBodyBin))) TryPrintTraceObj("---------------- -------- ----------------", respBodyBin, "") - fmt.Println("---------------- -------- ----------------") - fmt.Println("") + TPrintln("---------------- -------- ----------------") + TPrintln("") if resp.StatusCode != 200 { TestFail(t, "Statuscode != 200") @@ -166,7 +166,7 @@ func RequestAny[TResult any](t *testing.T, akey string, method string, baseURL s func RequestAuthAnyShouldFail(t *testing.T, akey string, method string, baseURL string, urlSuffix string, body any, statusCode int, errcode apierr.APIError) { client := http.Client{} - fmt.Printf("[-> REQUEST] (%s) %s%s [%s] (should-fail with %d/%d)\n", method, baseURL, urlSuffix, langext.Conditional(akey == "", "NO AUTH", "AUTH"), statusCode, errcode) + TPrintf("[-> REQUEST] (%s) %s%s [%s] (should-fail with %d/%d)\n", method, baseURL, urlSuffix, langext.Conditional(akey == "", "NO AUTH", "AUTH"), statusCode, errcode) bytesbody := make([]byte, 0) contentType := "" @@ -221,14 +221,14 @@ func RequestAuthAnyShouldFail(t *testing.T, akey string, method string, baseURL TestFailErr(t, err) } - fmt.Println("") - fmt.Printf("---------------- RESPONSE (%d) ----------------\n", resp.StatusCode) - fmt.Println(langext.TryPrettyPrintJson(string(respBodyBin))) + TPrintln("") + TPrintf("---------------- RESPONSE (%d) ----------------\n", resp.StatusCode) + TPrintln(langext.TryPrettyPrintJson(string(respBodyBin))) if (statusCode != 0 && resp.StatusCode != statusCode) || (statusCode == 0 && resp.StatusCode == 200) { TryPrintTraceObj("---------------- -------- ----------------", respBodyBin, "") } - fmt.Println("---------------- -------- ----------------") - fmt.Println("") + TPrintln("---------------- -------- ----------------") + TPrintln("") if statusCode != 0 && resp.StatusCode != statusCode { TestFailFmt(t, "Statuscode != %d (expected failure)", statusCode) @@ -267,13 +267,13 @@ func TryPrintTraceObj(prefix string, body []byte, suffix string) { if v2, ok := v1["traceObj"]; ok { if v3, ok := v2.(string); ok { if prefix != "" { - fmt.Println(prefix) + TPrintln(prefix) } - fmt.Println(strings.TrimSpace(v3)) + TPrintln(strings.TrimSpace(v3)) if suffix != "" { - fmt.Println(suffix) + TPrintln(suffix) } } } diff --git a/server/test/util/webserver.go b/server/test/util/webserver.go index 2811d5f..eebaee8 100644 --- a/server/test/util/webserver.go +++ b/server/test/util/webserver.go @@ -9,7 +9,6 @@ import ( "blackforestbytes.com/simplecloudnotifier/jobs" "blackforestbytes.com/simplecloudnotifier/logic" "blackforestbytes.com/simplecloudnotifier/push" - "fmt" "gogs.mikescher.com/BlackForestBytes/goext/langext" "os" "path/filepath" @@ -45,7 +44,7 @@ func StartSimpleWebserver(t *testing.T) (*logic.Application, func()) { TestFailErr(t, err) } - fmt.Println("DatabaseFile: " + dbfile) + TPrintln("DatabaseFile: " + dbfile) conf := scn.Config{ Namespace: "test",