summaryrefslogtreecommitdiffstats
path: root/modules/test
diff options
context:
space:
mode:
authorDaniel Baumann <daniel@debian.org>2024-10-18 20:33:49 +0200
committerDaniel Baumann <daniel@debian.org>2024-12-12 23:57:56 +0100
commite68b9d00a6e05b3a941f63ffb696f91e554ac5ec (patch)
tree97775d6c13b0f416af55314eb6a89ef792474615 /modules/test
parentInitial commit. (diff)
downloadforgejo-e68b9d00a6e05b3a941f63ffb696f91e554ac5ec.tar.xz
forgejo-e68b9d00a6e05b3a941f63ffb696f91e554ac5ec.zip
Adding upstream version 9.0.3.
Signed-off-by: Daniel Baumann <daniel@debian.org>
Diffstat (limited to 'modules/test')
-rw-r--r--modules/test/logchecker.go107
-rw-r--r--modules/test/logchecker_test.go58
-rw-r--r--modules/test/utils.go48
-rw-r--r--modules/test/utils_test.go18
4 files changed, 231 insertions, 0 deletions
diff --git a/modules/test/logchecker.go b/modules/test/logchecker.go
new file mode 100644
index 0000000..0f12257
--- /dev/null
+++ b/modules/test/logchecker.go
@@ -0,0 +1,107 @@
+// Copyright 2023 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package test
+
+import (
+ "context"
+ "fmt"
+ "strings"
+ "sync"
+ "sync/atomic"
+ "time"
+
+ "code.gitea.io/gitea/modules/log"
+)
+
+type LogChecker struct {
+ *log.EventWriterBaseImpl
+
+ filterMessages []string
+ filtered []bool
+
+ stopMark string
+ stopped bool
+
+ mu sync.Mutex
+}
+
+func (lc *LogChecker) Run(ctx context.Context) {
+ for {
+ select {
+ case <-ctx.Done():
+ return
+ case event, ok := <-lc.Queue:
+ if !ok {
+ return
+ }
+ lc.checkLogEvent(event)
+ }
+ }
+}
+
+func (lc *LogChecker) checkLogEvent(event *log.EventFormatted) {
+ lc.mu.Lock()
+ defer lc.mu.Unlock()
+ for i, msg := range lc.filterMessages {
+ if strings.Contains(event.Origin.MsgSimpleText, msg) {
+ lc.filtered[i] = true
+ }
+ }
+ if strings.Contains(event.Origin.MsgSimpleText, lc.stopMark) {
+ lc.stopped = true
+ }
+}
+
+var checkerIndex int64
+
+func NewLogChecker(namePrefix string, level log.Level) (logChecker *LogChecker, cancel func()) {
+ logger := log.GetManager().GetLogger(namePrefix)
+ newCheckerIndex := atomic.AddInt64(&checkerIndex, 1)
+ writerName := namePrefix + "-" + fmt.Sprint(newCheckerIndex)
+
+ lc := &LogChecker{}
+ lc.EventWriterBaseImpl = log.NewEventWriterBase(writerName, "test-log-checker", log.WriterMode{
+ Level: level,
+ })
+ logger.AddWriters(lc)
+ return lc, func() { _ = logger.RemoveWriter(writerName) }
+}
+
+// Filter will make the `Check` function to check if these logs are outputted.
+func (lc *LogChecker) Filter(msgs ...string) *LogChecker {
+ lc.mu.Lock()
+ defer lc.mu.Unlock()
+ lc.filterMessages = make([]string, len(msgs))
+ copy(lc.filterMessages, msgs)
+ lc.filtered = make([]bool, len(lc.filterMessages))
+ return lc
+}
+
+func (lc *LogChecker) StopMark(msg string) *LogChecker {
+ lc.mu.Lock()
+ defer lc.mu.Unlock()
+ lc.stopMark = msg
+ lc.stopped = false
+ return lc
+}
+
+// Check returns the filtered slice and whether the stop mark is reached.
+func (lc *LogChecker) Check(d time.Duration) (filtered []bool, stopped bool) {
+ stop := time.Now().Add(d)
+
+ for {
+ lc.mu.Lock()
+ stopped = lc.stopped
+ lc.mu.Unlock()
+
+ if time.Now().After(stop) || stopped {
+ lc.mu.Lock()
+ f := make([]bool, len(lc.filtered))
+ copy(f, lc.filtered)
+ lc.mu.Unlock()
+ return f, stopped
+ }
+ time.Sleep(10 * time.Millisecond)
+ }
+}
diff --git a/modules/test/logchecker_test.go b/modules/test/logchecker_test.go
new file mode 100644
index 0000000..0f410fe
--- /dev/null
+++ b/modules/test/logchecker_test.go
@@ -0,0 +1,58 @@
+// Copyright 2023 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package test
+
+import (
+ "testing"
+ "time"
+
+ "code.gitea.io/gitea/modules/log"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestLogCheckerInfo(t *testing.T) {
+ lc, cleanup := NewLogChecker(log.DEFAULT, log.INFO)
+ defer cleanup()
+
+ lc.Filter("First", "Third").StopMark("End")
+ log.Info("test")
+
+ filtered, stopped := lc.Check(100 * time.Millisecond)
+ assert.ElementsMatch(t, []bool{false, false}, filtered)
+ assert.False(t, stopped)
+
+ log.Info("First")
+ log.Debug("Third")
+ filtered, stopped = lc.Check(100 * time.Millisecond)
+ assert.ElementsMatch(t, []bool{true, false}, filtered)
+ assert.False(t, stopped)
+
+ log.Info("Second")
+ log.Debug("Third")
+ filtered, stopped = lc.Check(100 * time.Millisecond)
+ assert.ElementsMatch(t, []bool{true, false}, filtered)
+ assert.False(t, stopped)
+
+ log.Info("Third")
+ filtered, stopped = lc.Check(100 * time.Millisecond)
+ assert.ElementsMatch(t, []bool{true, true}, filtered)
+ assert.False(t, stopped)
+
+ log.Info("End")
+ filtered, stopped = lc.Check(100 * time.Millisecond)
+ assert.ElementsMatch(t, []bool{true, true}, filtered)
+ assert.True(t, stopped)
+}
+
+func TestLogCheckerDebug(t *testing.T) {
+ lc, cleanup := NewLogChecker(log.DEFAULT, log.DEBUG)
+ defer cleanup()
+
+ lc.StopMark("End")
+
+ log.Debug("End")
+ _, stopped := lc.Check(100 * time.Millisecond)
+ assert.True(t, stopped)
+}
diff --git a/modules/test/utils.go b/modules/test/utils.go
new file mode 100644
index 0000000..3d884b6
--- /dev/null
+++ b/modules/test/utils.go
@@ -0,0 +1,48 @@
+// Copyright 2017 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package test
+
+import (
+ "net/http"
+ "net/http/httptest"
+ "strings"
+
+ "code.gitea.io/gitea/modules/json"
+)
+
+// RedirectURL returns the redirect URL of a http response.
+// It also works for JSONRedirect: `{"redirect": "..."}`
+func RedirectURL(resp http.ResponseWriter) string {
+ loc := resp.Header().Get("Location")
+ if loc != "" {
+ return loc
+ }
+ if r, ok := resp.(*httptest.ResponseRecorder); ok {
+ m := map[string]any{}
+ err := json.Unmarshal(r.Body.Bytes(), &m)
+ if err == nil {
+ if loc, ok := m["redirect"].(string); ok {
+ return loc
+ }
+ }
+ }
+ return ""
+}
+
+func IsNormalPageCompleted(s string) bool {
+ return strings.Contains(s, `<footer class="page-footer"`) && strings.Contains(s, `</html>`)
+}
+
+// use for global variables only
+func MockVariableValue[T any](p *T, v T) (reset func()) {
+ old := *p
+ *p = v
+ return func() { *p = old }
+}
+
+// use for global variables only
+func MockProtect[T any](p *T) (reset func()) {
+ old := *p
+ return func() { *p = old }
+}
diff --git a/modules/test/utils_test.go b/modules/test/utils_test.go
new file mode 100644
index 0000000..a3be74e
--- /dev/null
+++ b/modules/test/utils_test.go
@@ -0,0 +1,18 @@
+// Copyright 2024 The Forgejo Authors
+// SPDX-License-Identifier: MIT
+
+package test
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestMockProtect(t *testing.T) {
+ mockable := "original"
+ restore := MockProtect(&mockable)
+ mockable = "tainted"
+ restore()
+ assert.Equal(t, "original", mockable)
+}