burst_test.go 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. /*
  2. * Copyright (c) 2020, Psiphon Inc.
  3. * All rights reserved.
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. *
  18. */
  19. package common
  20. import (
  21. "testing"
  22. "time"
  23. )
  24. func TestBurstMonitoredConn(t *testing.T) {
  25. upstreamTargetBytes := int64(100000)
  26. downstreamTargetBytes := int64(1000000)
  27. burstDeadline := 1 * time.Second
  28. baseTime := time.Now()
  29. dummy := &dummyConn{}
  30. conn := NewBurstMonitoredConn(
  31. dummy,
  32. true,
  33. upstreamTargetBytes,
  34. burstDeadline,
  35. downstreamTargetBytes,
  36. burstDeadline)
  37. // Simulate 128KB/s up, 1MB/s down; transmit >= min bytes in segments; sets "first" and "min"
  38. dummy.SetRateLimits(131072, 1048576)
  39. segments := 10
  40. b := make([]byte, int(upstreamTargetBytes)/segments)
  41. firstReadStart := time.Now()
  42. for i := 0; i < segments; i++ {
  43. conn.Read(b)
  44. }
  45. firstReadEnd := time.Now()
  46. b = make([]byte, int(downstreamTargetBytes)/segments)
  47. firstWriteStart := time.Now()
  48. for i := 0; i < segments; i++ {
  49. conn.Write(b)
  50. }
  51. firstWriteEnd := time.Now()
  52. time.Sleep(burstDeadline * 2)
  53. // Simulate 1MB/s up, 10MB/s down; repeatedly transmit < min bytes before deadline; ignored
  54. dummy.SetRateLimits(1048576, 10485760)
  55. b = make([]byte, 1)
  56. segments = 1000
  57. for i := 0; i < segments; i++ {
  58. conn.Read(b)
  59. }
  60. for i := 0; i < segments; i++ {
  61. conn.Write(b)
  62. }
  63. time.Sleep(burstDeadline * 2)
  64. // Simulate 512Kb/s up, 5MB/s down; transmit >= min bytes; sets "max"
  65. dummy.SetRateLimits(524288, 5242880)
  66. maxReadStart := time.Now()
  67. conn.Read(make([]byte, upstreamTargetBytes))
  68. maxReadEnd := time.Now()
  69. maxWriteStart := time.Now()
  70. conn.Write(make([]byte, downstreamTargetBytes))
  71. maxWriteEnd := time.Now()
  72. time.Sleep(burstDeadline * 2)
  73. // Simulate 256Kb/s up, 2MB/s down;, transmit >= min bytes; sets "last"
  74. dummy.SetRateLimits(262144, 2097152)
  75. lastReadStart := time.Now()
  76. conn.Read(make([]byte, upstreamTargetBytes))
  77. lastReadEnd := time.Now()
  78. lastWriteStart := time.Now()
  79. conn.Write(make([]byte, downstreamTargetBytes))
  80. lastWriteEnd := time.Now()
  81. time.Sleep(burstDeadline * 2)
  82. conn.Close()
  83. t.Logf("upstream first: %d bytes in %s; %d bytes/s",
  84. conn.readBursts.first.bytes, conn.readBursts.first.duration(), conn.readBursts.first.rate())
  85. t.Logf("upstream last: %d bytes in %s; %d bytes/s",
  86. conn.readBursts.last.bytes, conn.readBursts.last.duration(), conn.readBursts.last.rate())
  87. t.Logf("upstream min: %d bytes in %s; %d bytes/s",
  88. conn.readBursts.min.bytes, conn.readBursts.min.duration(), conn.readBursts.min.rate())
  89. t.Logf("upstream max: %d bytes in %s; %d bytes/s",
  90. conn.readBursts.max.bytes, conn.readBursts.max.duration(), conn.readBursts.max.rate())
  91. t.Logf("downstream first: %d bytes in %s; %d bytes/s",
  92. conn.writeBursts.first.bytes, conn.writeBursts.first.duration(), conn.writeBursts.first.rate())
  93. t.Logf("downstream last: %d bytes in %s; %d bytes/s",
  94. conn.writeBursts.last.bytes, conn.writeBursts.last.duration(), conn.writeBursts.last.rate())
  95. t.Logf("downstream min: %d bytes in %s; %d bytes/s",
  96. conn.writeBursts.min.bytes, conn.writeBursts.min.duration(), conn.writeBursts.min.rate())
  97. t.Logf("downstream max: %d bytes in %s; %d bytes/s",
  98. conn.writeBursts.max.bytes, conn.writeBursts.max.duration(), conn.writeBursts.max.rate())
  99. logFields := conn.GetMetrics(baseTime)
  100. if len(logFields) != 32 {
  101. t.Errorf("unexpected metric count: %d", len(logFields))
  102. }
  103. for name, expectedValue := range map[string]int64{
  104. "burst_upstream_first_offset": int64(firstReadStart.Sub(baseTime) / time.Millisecond),
  105. "burst_upstream_first_duration": int64(firstReadEnd.Sub(firstReadStart) / time.Millisecond),
  106. "burst_upstream_first_bytes": upstreamTargetBytes,
  107. "burst_upstream_first_rate": 131072,
  108. "burst_upstream_last_offset": int64(lastReadStart.Sub(baseTime) / time.Millisecond),
  109. "burst_upstream_last_duration": int64(lastReadEnd.Sub(lastReadStart) / time.Millisecond),
  110. "burst_upstream_last_bytes": upstreamTargetBytes,
  111. "burst_upstream_last_rate": 262144,
  112. "burst_upstream_min_offset": int64(firstReadStart.Sub(baseTime) / time.Millisecond),
  113. "burst_upstream_min_duration": int64(firstReadEnd.Sub(firstReadStart) / time.Millisecond),
  114. "burst_upstream_min_bytes": upstreamTargetBytes,
  115. "burst_upstream_min_rate": 131072,
  116. "burst_upstream_max_offset": int64(maxReadStart.Sub(baseTime) / time.Millisecond),
  117. "burst_upstream_max_duration": int64(maxReadEnd.Sub(maxReadStart) / time.Millisecond),
  118. "burst_upstream_max_bytes": upstreamTargetBytes,
  119. "burst_upstream_max_rate": 524288,
  120. "burst_downstream_first_offset": int64(firstWriteStart.Sub(baseTime) / time.Millisecond),
  121. "burst_downstream_first_duration": int64(firstWriteEnd.Sub(firstWriteStart) / time.Millisecond),
  122. "burst_downstream_first_bytes": downstreamTargetBytes,
  123. "burst_downstream_first_rate": 1048576,
  124. "burst_downstream_last_offset": int64(lastWriteStart.Sub(baseTime) / time.Millisecond),
  125. "burst_downstream_last_duration": int64(lastWriteEnd.Sub(lastWriteStart) / time.Millisecond),
  126. "burst_downstream_last_bytes": downstreamTargetBytes,
  127. "burst_downstream_last_rate": 2097152,
  128. "burst_downstream_min_offset": int64(firstWriteStart.Sub(baseTime) / time.Millisecond),
  129. "burst_downstream_min_duration": int64(firstWriteEnd.Sub(firstWriteStart) / time.Millisecond),
  130. "burst_downstream_min_bytes": downstreamTargetBytes,
  131. "burst_downstream_min_rate": 1048576,
  132. "burst_downstream_max_offset": int64(maxWriteStart.Sub(baseTime) / time.Millisecond),
  133. "burst_downstream_max_duration": int64(maxWriteEnd.Sub(maxWriteStart) / time.Millisecond),
  134. "burst_downstream_max_bytes": downstreamTargetBytes,
  135. "burst_downstream_max_rate": 5242880,
  136. } {
  137. value, ok := logFields[name]
  138. if !ok {
  139. t.Errorf("missing expected metric: %s", name)
  140. continue
  141. }
  142. valueInt64, ok := value.(int64)
  143. if !ok {
  144. t.Errorf("missing expected metric type: %s (%T)", name, value)
  145. continue
  146. }
  147. minAcceptable := int64(float64(expectedValue) * 0.90)
  148. maxAcceptable := int64(float64(expectedValue) * 1.10)
  149. if valueInt64 < minAcceptable || valueInt64 > maxAcceptable {
  150. t.Errorf("unexpected metric value: %s (%v <= %v <= %v)",
  151. name, minAcceptable, valueInt64, maxAcceptable)
  152. continue
  153. }
  154. }
  155. }