dashboard_test.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. package dashboard
  2. import (
  3. "bufio"
  4. "os"
  5. "sync"
  6. "testing"
  7. "time"
  8. //"fmt"
  9. "github.com/flashmob/go-guerrilla/log"
  10. "regexp"
  11. "strings"
  12. )
  13. func TestRunStop(t *testing.T) {
  14. config := &Config{
  15. Enabled: true,
  16. ListenInterface: ":8082",
  17. TickInterval: "5s",
  18. MaxWindow: "24h",
  19. RankingUpdateInterval: "6h",
  20. }
  21. var wg sync.WaitGroup
  22. wg.Add(1)
  23. go func() {
  24. Run(config)
  25. wg.Done()
  26. }()
  27. // give Run some time to start
  28. time.Sleep(time.Second)
  29. Stop()
  30. // Wait for Run() to exit
  31. wg.Wait()
  32. }
  33. // Test if starting with a bad interface address
  34. func TestRunStopBadAddress(t *testing.T) {
  35. config := &Config{
  36. Enabled: true,
  37. ListenInterface: "1.1.1.1:0",
  38. TickInterval: "5s",
  39. MaxWindow: "24h",
  40. RankingUpdateInterval: "6h",
  41. }
  42. var wg sync.WaitGroup
  43. wg.Add(1)
  44. go func() {
  45. Run(config)
  46. wg.Done()
  47. }()
  48. time.Sleep(time.Second * 2)
  49. Stop()
  50. // Wait for Run() to exit
  51. wg.Wait()
  52. }
  53. // Run a simulation from an already captured log
  54. func TestSimulationRun(t *testing.T) {
  55. config := &Config{
  56. Enabled: true,
  57. ListenInterface: ":8082",
  58. TickInterval: "1s",
  59. MaxWindow: "24h",
  60. RankingUpdateInterval: "6h",
  61. }
  62. var wg sync.WaitGroup
  63. wg.Add(1)
  64. go func() {
  65. Run(config)
  66. wg.Done()
  67. }()
  68. // give Run some time to start
  69. time.Sleep(time.Second)
  70. file, err := os.Open("simulation.log")
  71. if err != nil {
  72. panic(err.Error())
  73. }
  74. defer file.Close()
  75. reader := bufio.NewReader(file)
  76. scanner := bufio.NewScanner(reader)
  77. scanner.Split(bufio.ScanLines)
  78. l, _ := log.GetLogger("stderr", "info")
  79. l.AddHook(LogHook)
  80. // match with quotes or without, ie. time="..." or level=
  81. r := regexp.MustCompile(`(.+?)=("[^"]*"|\S*)\s*`)
  82. c := 0
  83. simStart := time.Now()
  84. var start time.Time
  85. for scanner.Scan() {
  86. fields := map[string]interface{}{}
  87. line := scanner.Text()
  88. items := r.FindAllString(line, -1)
  89. msg := ""
  90. var logElapsed time.Duration
  91. for i := range items {
  92. key, val := parseItem(items[i])
  93. //fmt.Println(key, val)
  94. if key != "time" && key != "level" && key != "msg" {
  95. fields[key] = val
  96. }
  97. if key == "msg" {
  98. msg = val
  99. }
  100. if key == "time" {
  101. tv, err := time.Parse(time.RFC3339, val)
  102. if err != nil {
  103. t.Error("invalid time", tv)
  104. }
  105. if start.IsZero() {
  106. start = tv
  107. }
  108. fields["start"] = start
  109. logElapsed = tv.Sub(start)
  110. }
  111. }
  112. diff := time.Now().Sub(simStart) - logElapsed
  113. time.Sleep(diff) // wait so that we don't go too fast
  114. simStart = simStart.Add(diff) // catch up
  115. l.WithFields(fields).Info(msg)
  116. c++
  117. if c > 5000 {
  118. break
  119. }
  120. }
  121. Stop()
  122. // Wait for Run() to exit
  123. wg.Wait()
  124. }
  125. // parseItem parses a log item, eg time="2017-03-24T11:55:44+11:00" will be:
  126. // key = time and val will be 2017-03-24T11:55:44+11:00
  127. func parseItem(item string) (key string, val string) {
  128. arr := strings.Split(item, "=")
  129. if len(arr) == 2 {
  130. key = arr[0]
  131. if arr[1][0:1] == "\"" {
  132. pos := len(arr[1]) - 2
  133. val = arr[1][1:pos]
  134. } else {
  135. val = arr[1]
  136. }
  137. }
  138. val = strings.TrimSpace(val)
  139. return
  140. }