buffer_test.go 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. package util
  2. import (
  3. "bytes"
  4. "math"
  5. "math/rand"
  6. "runtime"
  7. "strings"
  8. "testing"
  9. "time"
  10. )
  11. func TestBufferReadWrite(t *testing.T) {
  12. buf := NewBuffer()
  13. buf.WriteBool(true)
  14. buf.WriteInt(42)
  15. buf.WriteFloat64(3.14)
  16. buf.WriteString("Testing, 1, 2, 3!")
  17. readBuf := NewBufferFromBytes(buf.Bytes())
  18. boolVal := readBuf.ReadBool()
  19. intVal := readBuf.ReadInt()
  20. floatVal := readBuf.ReadFloat64()
  21. stringVal := readBuf.ReadString()
  22. if boolVal != true {
  23. t.Errorf("Expected bool value to be true, got %v", boolVal)
  24. }
  25. if intVal != 42 {
  26. t.Errorf("Expected int value to be 42, got %v", intVal)
  27. }
  28. if floatVal != 3.14 {
  29. t.Errorf("Expected float value to be 3.14, got %v", floatVal)
  30. }
  31. if stringVal != "Testing, 1, 2, 3!" {
  32. t.Errorf("Expected string value to be 'Hello, World!', got %v", stringVal)
  33. }
  34. }
  35. func TestBufferWriteReadBytes(t *testing.T) {
  36. buf := NewBuffer()
  37. bytesToWrite := []byte{0x01, 0x02, 0x03, 0x04}
  38. buf.WriteBytes(bytesToWrite)
  39. readBuf := NewBufferFromBytes(buf.Bytes())
  40. readBytes := readBuf.ReadBytes(len(bytesToWrite))
  41. if !bytes.Equal(readBytes, bytesToWrite) {
  42. t.Errorf("Expected bytes to be %v, got %v", bytesToWrite, readBytes)
  43. }
  44. }
  45. func TestBufferWriteReadUInt64(t *testing.T) {
  46. buf := NewBuffer()
  47. uint64Val := uint64(1234567890)
  48. buf.WriteUInt64(uint64Val)
  49. readBuf := NewBufferFromBytes(buf.Bytes())
  50. readUInt64 := readBuf.ReadUInt64()
  51. if readUInt64 != uint64Val {
  52. t.Errorf("Expected uint64 value to be %v, got %v", uint64Val, readUInt64)
  53. }
  54. }
  55. func TestBufferWriteReadFloat32(t *testing.T) {
  56. buf := NewBuffer()
  57. float32Val := float32(3.14159)
  58. buf.WriteFloat32(float32Val)
  59. readBuf := NewBufferFromBytes(buf.Bytes())
  60. readFloat32 := readBuf.ReadFloat32()
  61. if readFloat32 != float32Val {
  62. t.Errorf("Expected float32 value to be %v, got %v", float32Val, readFloat32)
  63. }
  64. }
  65. func TestBufferWriteReadInt8(t *testing.T) {
  66. buf := NewBuffer()
  67. int8Val := int8(-42)
  68. buf.WriteInt8(int8Val)
  69. readBuf := NewBufferFromBytes(buf.Bytes())
  70. readInt8 := readBuf.ReadInt8()
  71. if readInt8 != int8Val {
  72. t.Errorf("Expected int8 value to be %v, got %v", int8Val, readInt8)
  73. }
  74. }
  75. func TestBufferWriteReadUInt16(t *testing.T) {
  76. buf := NewBuffer()
  77. uint16Val := uint16(65535)
  78. buf.WriteUInt16(uint16Val)
  79. readBuf := NewBufferFromBytes(buf.Bytes())
  80. readUInt16 := readBuf.ReadUInt16()
  81. if readUInt16 != uint16Val {
  82. t.Errorf("Expected uint16 value to be %v, got %v", uint16Val, readUInt16)
  83. }
  84. }
  85. func TestBufferWriteReadInt32(t *testing.T) {
  86. buf := NewBuffer()
  87. int32Val := int32(-1234567890)
  88. buf.WriteInt32(int32Val)
  89. readBuf := NewBufferFromBytes(buf.Bytes())
  90. readInt32 := readBuf.ReadInt32()
  91. if readInt32 != int32Val {
  92. t.Errorf("Expected int32 value to be %v, got %v", int32Val, readInt32)
  93. }
  94. }
  95. func TestBufferWriteReadUInt8(t *testing.T) {
  96. buf := NewBuffer()
  97. uint8Val := uint8(255)
  98. buf.WriteUInt8(uint8Val)
  99. readBuf := NewBufferFromBytes(buf.Bytes())
  100. readUInt8 := readBuf.ReadUInt8()
  101. if readUInt8 != uint8Val {
  102. t.Errorf("Expected uint8 value to be %v, got %v", uint8Val, readUInt8)
  103. }
  104. }
  105. func TestBufferWriteReadInt16(t *testing.T) {
  106. buf := NewBuffer()
  107. int16Val := int16(-32768)
  108. buf.WriteInt16(int16Val)
  109. readBuf := NewBufferFromBytes(buf.Bytes())
  110. readInt16 := readBuf.ReadInt16()
  111. if readInt16 != int16Val {
  112. t.Errorf("Expected int16 value to be %v, got %v", int16Val, readInt16)
  113. }
  114. }
  115. func TestBufferWriteReadUInt32(t *testing.T) {
  116. buf := NewBuffer()
  117. uint32Val := uint32(4294967295)
  118. buf.WriteUInt32(uint32Val)
  119. readBuf := NewBufferFromBytes(buf.Bytes())
  120. readUInt32 := readBuf.ReadUInt32()
  121. if readUInt32 != uint32Val {
  122. t.Errorf("Expected uint32 value to be %v, got %v", uint32Val, readUInt32)
  123. }
  124. }
  125. func TestBufferWriteReadInt64(t *testing.T) {
  126. buf := NewBuffer()
  127. int64Val := int64(-9223372036854775808)
  128. buf.WriteInt64(int64Val)
  129. readBuf := NewBufferFromBytes(buf.Bytes())
  130. readInt64 := readBuf.ReadInt64()
  131. if readInt64 != int64Val {
  132. t.Errorf("Expected int64 value to be %v, got %v", int64Val, readInt64)
  133. }
  134. }
  135. func TestBufferBytes(t *testing.T) {
  136. buf := NewBuffer()
  137. buf.WriteInt(42)
  138. buf.WriteFloat64(3.14)
  139. unreadBytes := buf.Bytes()
  140. newBuf := NewBufferFromBytes(unreadBytes)
  141. intVal := newBuf.ReadInt()
  142. floatVal := newBuf.ReadFloat64()
  143. if intVal != 42 {
  144. t.Errorf("Expected int value to be 42, got %v", intVal)
  145. }
  146. if floatVal != 3.14 {
  147. t.Errorf("Expected float value to be 3.14, got %v", floatVal)
  148. }
  149. }
  150. func TestBufferNewBufferFrom(t *testing.T) {
  151. buf := NewBuffer()
  152. buf.WriteInt(42)
  153. buf.WriteFloat64(3.14)
  154. newBuf := NewBufferFrom(buf)
  155. intVal := newBuf.ReadInt()
  156. floatVal := newBuf.ReadFloat64()
  157. if intVal != 42 {
  158. t.Errorf("Expected int value to be 42, got %v", intVal)
  159. }
  160. if floatVal != 3.14 {
  161. t.Errorf("Expected float value to be 3.14, got %v", floatVal)
  162. }
  163. }
  164. const letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
  165. func generateRandomString(ln int) string {
  166. b := make([]byte, ln)
  167. for i := range b {
  168. b[i] = letters[rand.Intn(len(letters))]
  169. }
  170. return string(b)
  171. }
  172. func memMib() float64 {
  173. var m runtime.MemStats
  174. runtime.ReadMemStats(&m)
  175. return float64(m.Alloc) / 1024.0 / 1024.0
  176. }
  177. func TestStringBytes(t *testing.T) {
  178. baselineMem := memMib()
  179. b := make([]byte, 10<<20)
  180. afterMem := memMib()
  181. delta := afterMem - baselineMem
  182. t.Logf("Allocated %v MiB, Delta: %v MiB", afterMem, delta)
  183. s := "Hello World!"
  184. sl := b[512 : 512+len(s)]
  185. copy(sl, stringToBytes(s))
  186. afterMem = memMib()
  187. delta = afterMem - baselineMem
  188. t.Logf("Allocated %v MiB, Delta: %v MiB", afterMem, delta)
  189. // this should pin the large backing array in memory, preventing it from being GC'd
  190. newS := bytesToString(sl)
  191. runtime.GC()
  192. time.Sleep(time.Second)
  193. afterMem = memMib()
  194. delta = afterMem - baselineMem
  195. t.Logf("S: %s, Allocated %v MiB, Delta: %v MiB", newS, afterMem, delta)
  196. // copy the string into a new string and clear out pinned string
  197. sCopy := strings.Clone(newS)
  198. newS = ""
  199. // Now that we've dropped the reference to the pinned backing array, it should be GC'd
  200. runtime.GC()
  201. time.Sleep(time.Second)
  202. afterMem = memMib()
  203. delta = afterMem - baselineMem
  204. t.Logf("S: %s, Allocated %v MiB, Delta: %v MiB", sCopy, afterMem, delta)
  205. if sCopy != s {
  206. t.Errorf("Expected string to be %v, got %v", s, sCopy)
  207. }
  208. if delta > 0.5 {
  209. t.Errorf("Expected memory delta to be less than 0.5 MiB, got %v MiB", delta)
  210. }
  211. }
  212. func TestTooLargeStringTruncate(t *testing.T) {
  213. normalStr := generateRandomString(100)
  214. bigStr := generateRandomString(math.MaxUint16 + (math.MaxUint16 / 2))
  215. expectedBigStrRead := bigStr[:math.MaxUint16]
  216. otherBigStr := generateRandomString(math.MaxUint16)
  217. plusOne := generateRandomString(math.MaxUint16 + 1)
  218. expectedPlusOne := plusOne[:math.MaxUint16]
  219. buf := NewBuffer()
  220. buf.WriteInt(42)
  221. buf.WriteFloat64(3.14)
  222. buf.WriteString(normalStr)
  223. buf.WriteString(bigStr)
  224. buf.WriteString(otherBigStr)
  225. buf.WriteString(plusOne)
  226. readBuf := NewBufferFromBytes(buf.Bytes())
  227. intVal := readBuf.ReadInt()
  228. floatVal := readBuf.ReadFloat64()
  229. normalStrRead := readBuf.ReadString()
  230. bigStrRead := readBuf.ReadString()
  231. otherBigStrRead := readBuf.ReadString()
  232. plusOneRead := readBuf.ReadString()
  233. if intVal != 42 {
  234. t.Errorf("Expected int value to be 42, got %v", intVal)
  235. }
  236. if floatVal != 3.14 {
  237. t.Errorf("Expected float value to be 3.14, got %v", floatVal)
  238. }
  239. if normalStrRead != normalStr {
  240. t.Errorf("Expected string value to be %v, got %v", normalStr, normalStrRead)
  241. }
  242. if bigStrRead != expectedBigStrRead {
  243. t.Errorf("Expected large string values to be equivalent!")
  244. }
  245. if otherBigStrRead != otherBigStr {
  246. t.Errorf("Expected large string values to be equivalent!")
  247. }
  248. if plusOneRead != expectedPlusOne {
  249. t.Errorf("Expected large string values to be equivalent!")
  250. }
  251. }