loading up the forgejo repo on tangled to test page performance
1// Copyright 2023 The Gitea Authors. All rights reserved.
2// SPDX-License-Identifier: MIT
3
4package test
5
6import (
7 "context"
8 "fmt"
9 "strings"
10 "sync"
11 "sync/atomic"
12 "time"
13
14 "forgejo.org/modules/log"
15)
16
17type LogChecker struct {
18 *log.EventWriterBaseImpl
19
20 filterMessages []string
21 filtered []bool
22
23 stopMark string
24 stopped bool
25
26 mu sync.Mutex
27}
28
29func (lc *LogChecker) Run(ctx context.Context) {
30 for {
31 select {
32 case <-ctx.Done():
33 return
34 case event, ok := <-lc.Queue:
35 if !ok {
36 return
37 }
38 lc.checkLogEvent(event)
39 }
40 }
41}
42
43func (lc *LogChecker) checkLogEvent(event *log.EventFormatted) {
44 lc.mu.Lock()
45 defer lc.mu.Unlock()
46 for i, msg := range lc.filterMessages {
47 if strings.Contains(event.Origin.MsgSimpleText, msg) {
48 lc.filtered[i] = true
49 }
50 }
51 if strings.Contains(event.Origin.MsgSimpleText, lc.stopMark) {
52 lc.stopped = true
53 }
54}
55
56var checkerIndex int64
57
58func NewLogChecker(namePrefix string, level log.Level) (logChecker *LogChecker, cancel func()) {
59 logger := log.GetManager().GetLogger(namePrefix)
60 newCheckerIndex := atomic.AddInt64(&checkerIndex, 1)
61 writerName := namePrefix + "-" + fmt.Sprint(newCheckerIndex)
62
63 lc := &LogChecker{}
64 lc.EventWriterBaseImpl = log.NewEventWriterBase(writerName, "test-log-checker", log.WriterMode{
65 Level: level,
66 })
67 logger.AddWriters(lc)
68 return lc, func() { _ = logger.RemoveWriter(writerName) }
69}
70
71// Filter will make the `Check` function to check if these logs are outputted.
72func (lc *LogChecker) Filter(msgs ...string) *LogChecker {
73 lc.mu.Lock()
74 defer lc.mu.Unlock()
75 lc.filterMessages = make([]string, len(msgs))
76 copy(lc.filterMessages, msgs)
77 lc.filtered = make([]bool, len(lc.filterMessages))
78 return lc
79}
80
81func (lc *LogChecker) StopMark(msg string) *LogChecker {
82 lc.mu.Lock()
83 defer lc.mu.Unlock()
84 lc.stopMark = msg
85 lc.stopped = false
86 return lc
87}
88
89// Check returns the filtered slice and whether the stop mark is reached.
90func (lc *LogChecker) Check(d time.Duration) (filtered []bool, stopped bool) {
91 stop := time.Now().Add(d)
92
93 for {
94 lc.mu.Lock()
95 stopped = lc.stopped
96 lc.mu.Unlock()
97
98 if time.Now().After(stop) || stopped {
99 lc.mu.Lock()
100 f := make([]bool, len(lc.filtered))
101 copy(f, lc.filtered)
102 lc.mu.Unlock()
103 return f, stopped
104 }
105 time.Sleep(10 * time.Millisecond)
106 }
107}