You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

logchecker.go 2.2KB

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