telemetry_test.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. package bwtest
  2. import (
  3. "context"
  4. "net"
  5. "testing"
  6. "time"
  7. )
  8. func TestSummaryCoversSamplesBeyondRetentionWindow(t *testing.T) {
  9. c := NewClient()
  10. for i := 1; i <= 300; i++ {
  11. rate := 1.0
  12. if i == 1 {
  13. rate = 50
  14. }
  15. c.recordSampleLocked(&LiveSample{ElapsedSec: float64(i), TxBytes: int64(i) * 125000, RxBytes: int64(i) * 250000, TxMbps: rate, RxMbps: 2, JitterMs: float64(i), TxPackets: int64(i) * 10, RxPackets: int64(i) * 10, LostPackets: int64(i)})
  16. }
  17. if len(c.samples) != 200 {
  18. t.Fatal("unbounded history")
  19. }
  20. c.finalizeSummary()
  21. s := c.status.Summary
  22. if s.AvgTxMbps != 1 || s.AvgRxMbps != 2 || s.PeakTxMbps != 50 || s.AvgJitterMs != 150.5 {
  23. t.Fatalf("summary lost early samples: %+v", s)
  24. }
  25. if s.AvgLossPct < 4.76 || s.AvgLossPct > 4.77 {
  26. t.Fatal("loss not computed from full totals")
  27. }
  28. }
  29. func TestFailedSessionIsNotRecordedAsSuccessfulHistory(t *testing.T) {
  30. c := NewClient()
  31. c.status = TestStatus{SessionID: "failed", Error: "No UDP data received", Summary: &TestSummary{}}
  32. m := &Manager{client: c}
  33. m.GetTestStatus()
  34. if len(m.GetHistory()) != 0 {
  35. t.Fatal("failed session was recorded as successful")
  36. }
  37. c.status.Error = ""
  38. m.GetTestStatus()
  39. if len(m.GetHistory()) != 1 {
  40. t.Fatal("successful session not recorded")
  41. }
  42. }
  43. func TestObserversReceiveBroadcastAndCanUnsubscribe(t *testing.T) {
  44. c := NewClient()
  45. a, stopA := c.Subscribe()
  46. b, stopB := c.Subscribe()
  47. defer stopB()
  48. c.recordSampleLocked(&LiveSample{ElapsedSec: 1})
  49. if (<-a).ElapsedSec != 1 || (<-b).ElapsedSec != 1 {
  50. t.Fatal("observers competed for samples")
  51. }
  52. stopA()
  53. stopA()
  54. if _, ok := <-a; ok {
  55. t.Fatal("subscription was not closed")
  56. }
  57. c.recordSampleLocked(&LiveSample{ElapsedSec: 2})
  58. if (<-b).ElapsedSec != 2 {
  59. t.Fatal("other observer stopped")
  60. }
  61. }
  62. func TestZeroDurationRemainsContinuous(t *testing.T) {
  63. // A closed local port makes the background connection end immediately; this
  64. // checks normalization without sending traffic or waiting ten seconds.
  65. l, err := net.Listen("tcp", "127.0.0.1:0")
  66. if err != nil {
  67. t.Fatal(err)
  68. }
  69. port := l.Addr().(*net.TCPAddr).Port
  70. l.Close()
  71. c := NewClient()
  72. if err := c.Run(context.Background(), SessionRequest{Target: "127.0.0.1", Port: port, Duration: 0}); err != nil {
  73. t.Fatal(err)
  74. }
  75. defer c.Stop()
  76. if c.GetStatus().Duration != 0 {
  77. t.Fatal("continuous duration was replaced")
  78. }
  79. }
  80. func TestContinuousSessionSurvivesTenSecondsAndStops(t *testing.T) {
  81. if testing.Short() {
  82. t.Skip("continuous session integration test")
  83. }
  84. s := testServer(t)
  85. c := NewClient()
  86. defer c.Stop()
  87. if err := c.Run(context.Background(), SessionRequest{Target: "127.0.0.1", Port: s.config.Port, Protocol: "udp", Direction: "both", Duration: 0, BandwidthLimit: 100000}); err != nil {
  88. t.Fatal(err)
  89. }
  90. timer := time.NewTimer(11 * time.Second)
  91. defer timer.Stop()
  92. <-timer.C
  93. if st := c.GetStatus(); !st.Running || st.Error != "" || st.ElapsedSec < 10 {
  94. t.Fatalf("continuous session ended: %+v", st)
  95. }
  96. c.Stop()
  97. deadline := time.Now().Add(2 * time.Second)
  98. for c.GetStatus().Running && time.Now().Before(deadline) {
  99. time.Sleep(10 * time.Millisecond)
  100. }
  101. st := c.GetStatus()
  102. if st.Running || st.Summary == nil || st.Summary.TotalTxBytes == 0 || st.Summary.TotalRxBytes == 0 {
  103. t.Fatal("continuous session failed to stop or exchange data")
  104. }
  105. }