telemetry_test.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  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 TestObserversReceiveBroadcastAndCanUnsubscribe(t *testing.T) {
  30. c := NewClient()
  31. a, stopA := c.Subscribe()
  32. b, stopB := c.Subscribe()
  33. defer stopB()
  34. c.recordSampleLocked(&LiveSample{ElapsedSec: 1})
  35. if (<-a).ElapsedSec != 1 || (<-b).ElapsedSec != 1 {
  36. t.Fatal("observers competed for samples")
  37. }
  38. stopA()
  39. stopA()
  40. if _, ok := <-a; ok {
  41. t.Fatal("subscription was not closed")
  42. }
  43. c.recordSampleLocked(&LiveSample{ElapsedSec: 2})
  44. if (<-b).ElapsedSec != 2 {
  45. t.Fatal("other observer stopped")
  46. }
  47. }
  48. func TestZeroDurationRemainsContinuous(t *testing.T) {
  49. // A closed local port makes the background connection end immediately; this
  50. // checks normalization without sending traffic or waiting ten seconds.
  51. l, err := net.Listen("tcp", "127.0.0.1:0")
  52. if err != nil {
  53. t.Fatal(err)
  54. }
  55. port := l.Addr().(*net.TCPAddr).Port
  56. l.Close()
  57. c := NewClient()
  58. if err := c.Run(context.Background(), SessionRequest{Target: "127.0.0.1", Port: port, Duration: 0}); err != nil {
  59. t.Fatal(err)
  60. }
  61. defer c.Stop()
  62. if c.GetStatus().Duration != 0 {
  63. t.Fatal("continuous duration was replaced")
  64. }
  65. }
  66. func TestContinuousSessionSurvivesTenSecondsAndStops(t *testing.T) {
  67. if testing.Short() {
  68. t.Skip("continuous session integration test")
  69. }
  70. s := testServer(t)
  71. c := NewClient()
  72. defer c.Stop()
  73. 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 {
  74. t.Fatal(err)
  75. }
  76. timer := time.NewTimer(11 * time.Second)
  77. defer timer.Stop()
  78. <-timer.C
  79. if st := c.GetStatus(); !st.Running || st.Error != "" || st.ElapsedSec < 10 {
  80. t.Fatalf("continuous session ended: %+v", st)
  81. }
  82. c.Stop()
  83. deadline := time.Now().Add(2 * time.Second)
  84. for c.GetStatus().Running && time.Now().Before(deadline) {
  85. time.Sleep(10 * time.Millisecond)
  86. }
  87. st := c.GetStatus()
  88. if st.Running || st.Summary == nil || st.Summary.TotalTxBytes == 0 || st.Summary.TotalRxBytes == 0 {
  89. t.Fatal("continuous session failed to stop or exchange data")
  90. }
  91. }