You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

369 lines
9.3 KiB

  1. // Copyright 2009 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package util
  5. import (
  6. "bytes"
  7. "io"
  8. "math/rand"
  9. "runtime"
  10. "testing"
  11. )
  12. const N = 10000 // make this bigger for a larger (and slower) test
  13. var data string // test data for write tests
  14. var testBytes []byte // test data; same as data but as a slice.
  15. func init() {
  16. testBytes = make([]byte, N)
  17. for i := 0; i < N; i++ {
  18. testBytes[i] = 'a' + byte(i%26)
  19. }
  20. data = string(testBytes)
  21. }
  22. // Verify that contents of buf match the string s.
  23. func check(t *testing.T, testname string, buf *Buffer, s string) {
  24. bytes := buf.Bytes()
  25. str := buf.String()
  26. if buf.Len() != len(bytes) {
  27. t.Errorf("%s: buf.Len() == %d, len(buf.Bytes()) == %d", testname, buf.Len(), len(bytes))
  28. }
  29. if buf.Len() != len(str) {
  30. t.Errorf("%s: buf.Len() == %d, len(buf.String()) == %d", testname, buf.Len(), len(str))
  31. }
  32. if buf.Len() != len(s) {
  33. t.Errorf("%s: buf.Len() == %d, len(s) == %d", testname, buf.Len(), len(s))
  34. }
  35. if string(bytes) != s {
  36. t.Errorf("%s: string(buf.Bytes()) == %q, s == %q", testname, string(bytes), s)
  37. }
  38. }
  39. // Fill buf through n writes of byte slice fub.
  40. // The initial contents of buf corresponds to the string s;
  41. // the result is the final contents of buf returned as a string.
  42. func fillBytes(t *testing.T, testname string, buf *Buffer, s string, n int, fub []byte) string {
  43. check(t, testname+" (fill 1)", buf, s)
  44. for ; n > 0; n-- {
  45. m, err := buf.Write(fub)
  46. if m != len(fub) {
  47. t.Errorf(testname+" (fill 2): m == %d, expected %d", m, len(fub))
  48. }
  49. if err != nil {
  50. t.Errorf(testname+" (fill 3): err should always be nil, found err == %s", err)
  51. }
  52. s += string(fub)
  53. check(t, testname+" (fill 4)", buf, s)
  54. }
  55. return s
  56. }
  57. func TestNewBuffer(t *testing.T) {
  58. buf := NewBuffer(testBytes)
  59. check(t, "NewBuffer", buf, data)
  60. }
  61. // Empty buf through repeated reads into fub.
  62. // The initial contents of buf corresponds to the string s.
  63. func empty(t *testing.T, testname string, buf *Buffer, s string, fub []byte) {
  64. check(t, testname+" (empty 1)", buf, s)
  65. for {
  66. n, err := buf.Read(fub)
  67. if n == 0 {
  68. break
  69. }
  70. if err != nil {
  71. t.Errorf(testname+" (empty 2): err should always be nil, found err == %s", err)
  72. }
  73. s = s[n:]
  74. check(t, testname+" (empty 3)", buf, s)
  75. }
  76. check(t, testname+" (empty 4)", buf, "")
  77. }
  78. func TestBasicOperations(t *testing.T) {
  79. var buf Buffer
  80. for i := 0; i < 5; i++ {
  81. check(t, "TestBasicOperations (1)", &buf, "")
  82. buf.Reset()
  83. check(t, "TestBasicOperations (2)", &buf, "")
  84. buf.Truncate(0)
  85. check(t, "TestBasicOperations (3)", &buf, "")
  86. n, err := buf.Write([]byte(data[0:1]))
  87. if n != 1 {
  88. t.Errorf("wrote 1 byte, but n == %d", n)
  89. }
  90. if err != nil {
  91. t.Errorf("err should always be nil, but err == %s", err)
  92. }
  93. check(t, "TestBasicOperations (4)", &buf, "a")
  94. buf.WriteByte(data[1])
  95. check(t, "TestBasicOperations (5)", &buf, "ab")
  96. n, err = buf.Write([]byte(data[2:26]))
  97. if n != 24 {
  98. t.Errorf("wrote 25 bytes, but n == %d", n)
  99. }
  100. check(t, "TestBasicOperations (6)", &buf, string(data[0:26]))
  101. buf.Truncate(26)
  102. check(t, "TestBasicOperations (7)", &buf, string(data[0:26]))
  103. buf.Truncate(20)
  104. check(t, "TestBasicOperations (8)", &buf, string(data[0:20]))
  105. empty(t, "TestBasicOperations (9)", &buf, string(data[0:20]), make([]byte, 5))
  106. empty(t, "TestBasicOperations (10)", &buf, "", make([]byte, 100))
  107. buf.WriteByte(data[1])
  108. c, err := buf.ReadByte()
  109. if err != nil {
  110. t.Error("ReadByte unexpected eof")
  111. }
  112. if c != data[1] {
  113. t.Errorf("ReadByte wrong value c=%v", c)
  114. }
  115. c, err = buf.ReadByte()
  116. if err == nil {
  117. t.Error("ReadByte unexpected not eof")
  118. }
  119. }
  120. }
  121. func TestLargeByteWrites(t *testing.T) {
  122. var buf Buffer
  123. limit := 30
  124. if testing.Short() {
  125. limit = 9
  126. }
  127. for i := 3; i < limit; i += 3 {
  128. s := fillBytes(t, "TestLargeWrites (1)", &buf, "", 5, testBytes)
  129. empty(t, "TestLargeByteWrites (2)", &buf, s, make([]byte, len(data)/i))
  130. }
  131. check(t, "TestLargeByteWrites (3)", &buf, "")
  132. }
  133. func TestLargeByteReads(t *testing.T) {
  134. var buf Buffer
  135. for i := 3; i < 30; i += 3 {
  136. s := fillBytes(t, "TestLargeReads (1)", &buf, "", 5, testBytes[0:len(testBytes)/i])
  137. empty(t, "TestLargeReads (2)", &buf, s, make([]byte, len(data)))
  138. }
  139. check(t, "TestLargeByteReads (3)", &buf, "")
  140. }
  141. func TestMixedReadsAndWrites(t *testing.T) {
  142. var buf Buffer
  143. s := ""
  144. for i := 0; i < 50; i++ {
  145. wlen := rand.Intn(len(data))
  146. s = fillBytes(t, "TestMixedReadsAndWrites (1)", &buf, s, 1, testBytes[0:wlen])
  147. rlen := rand.Intn(len(data))
  148. fub := make([]byte, rlen)
  149. n, _ := buf.Read(fub)
  150. s = s[n:]
  151. }
  152. empty(t, "TestMixedReadsAndWrites (2)", &buf, s, make([]byte, buf.Len()))
  153. }
  154. func TestNil(t *testing.T) {
  155. var b *Buffer
  156. if b.String() != "<nil>" {
  157. t.Errorf("expected <nil>; got %q", b.String())
  158. }
  159. }
  160. func TestReadFrom(t *testing.T) {
  161. var buf Buffer
  162. for i := 3; i < 30; i += 3 {
  163. s := fillBytes(t, "TestReadFrom (1)", &buf, "", 5, testBytes[0:len(testBytes)/i])
  164. var b Buffer
  165. b.ReadFrom(&buf)
  166. empty(t, "TestReadFrom (2)", &b, s, make([]byte, len(data)))
  167. }
  168. }
  169. func TestWriteTo(t *testing.T) {
  170. var buf Buffer
  171. for i := 3; i < 30; i += 3 {
  172. s := fillBytes(t, "TestWriteTo (1)", &buf, "", 5, testBytes[0:len(testBytes)/i])
  173. var b Buffer
  174. buf.WriteTo(&b)
  175. empty(t, "TestWriteTo (2)", &b, s, make([]byte, len(data)))
  176. }
  177. }
  178. func TestNext(t *testing.T) {
  179. b := []byte{0, 1, 2, 3, 4}
  180. tmp := make([]byte, 5)
  181. for i := 0; i <= 5; i++ {
  182. for j := i; j <= 5; j++ {
  183. for k := 0; k <= 6; k++ {
  184. // 0 <= i <= j <= 5; 0 <= k <= 6
  185. // Check that if we start with a buffer
  186. // of length j at offset i and ask for
  187. // Next(k), we get the right bytes.
  188. buf := NewBuffer(b[0:j])
  189. n, _ := buf.Read(tmp[0:i])
  190. if n != i {
  191. t.Fatalf("Read %d returned %d", i, n)
  192. }
  193. bb := buf.Next(k)
  194. want := k
  195. if want > j-i {
  196. want = j - i
  197. }
  198. if len(bb) != want {
  199. t.Fatalf("in %d,%d: len(Next(%d)) == %d", i, j, k, len(bb))
  200. }
  201. for l, v := range bb {
  202. if v != byte(l+i) {
  203. t.Fatalf("in %d,%d: Next(%d)[%d] = %d, want %d", i, j, k, l, v, l+i)
  204. }
  205. }
  206. }
  207. }
  208. }
  209. }
  210. var readBytesTests = []struct {
  211. buffer string
  212. delim byte
  213. expected []string
  214. err error
  215. }{
  216. {"", 0, []string{""}, io.EOF},
  217. {"a\x00", 0, []string{"a\x00"}, nil},
  218. {"abbbaaaba", 'b', []string{"ab", "b", "b", "aaab"}, nil},
  219. {"hello\x01world", 1, []string{"hello\x01"}, nil},
  220. {"foo\nbar", 0, []string{"foo\nbar"}, io.EOF},
  221. {"alpha\nbeta\ngamma\n", '\n', []string{"alpha\n", "beta\n", "gamma\n"}, nil},
  222. {"alpha\nbeta\ngamma", '\n', []string{"alpha\n", "beta\n", "gamma"}, io.EOF},
  223. }
  224. func TestReadBytes(t *testing.T) {
  225. for _, test := range readBytesTests {
  226. buf := NewBuffer([]byte(test.buffer))
  227. var err error
  228. for _, expected := range test.expected {
  229. var bytes []byte
  230. bytes, err = buf.ReadBytes(test.delim)
  231. if string(bytes) != expected {
  232. t.Errorf("expected %q, got %q", expected, bytes)
  233. }
  234. if err != nil {
  235. break
  236. }
  237. }
  238. if err != test.err {
  239. t.Errorf("expected error %v, got %v", test.err, err)
  240. }
  241. }
  242. }
  243. func TestGrow(t *testing.T) {
  244. x := []byte{'x'}
  245. y := []byte{'y'}
  246. tmp := make([]byte, 72)
  247. for _, startLen := range []int{0, 100, 1000, 10000, 100000} {
  248. xBytes := bytes.Repeat(x, startLen)
  249. for _, growLen := range []int{0, 100, 1000, 10000, 100000} {
  250. buf := NewBuffer(xBytes)
  251. // If we read, this affects buf.off, which is good to test.
  252. readBytes, _ := buf.Read(tmp)
  253. buf.Grow(growLen)
  254. yBytes := bytes.Repeat(y, growLen)
  255. // Check no allocation occurs in write, as long as we're single-threaded.
  256. var m1, m2 runtime.MemStats
  257. runtime.ReadMemStats(&m1)
  258. buf.Write(yBytes)
  259. runtime.ReadMemStats(&m2)
  260. if runtime.GOMAXPROCS(-1) == 1 && m1.Mallocs != m2.Mallocs {
  261. t.Errorf("allocation occurred during write")
  262. }
  263. // Check that buffer has correct data.
  264. if !bytes.Equal(buf.Bytes()[0:startLen-readBytes], xBytes[readBytes:]) {
  265. t.Errorf("bad initial data at %d %d", startLen, growLen)
  266. }
  267. if !bytes.Equal(buf.Bytes()[startLen-readBytes:startLen-readBytes+growLen], yBytes) {
  268. t.Errorf("bad written data at %d %d", startLen, growLen)
  269. }
  270. }
  271. }
  272. }
  273. // Was a bug: used to give EOF reading empty slice at EOF.
  274. func TestReadEmptyAtEOF(t *testing.T) {
  275. b := new(Buffer)
  276. slice := make([]byte, 0)
  277. n, err := b.Read(slice)
  278. if err != nil {
  279. t.Errorf("read error: %v", err)
  280. }
  281. if n != 0 {
  282. t.Errorf("wrong count; got %d want 0", n)
  283. }
  284. }
  285. // Tests that we occasionally compact. Issue 5154.
  286. func TestBufferGrowth(t *testing.T) {
  287. var b Buffer
  288. buf := make([]byte, 1024)
  289. b.Write(buf[0:1])
  290. var cap0 int
  291. for i := 0; i < 5<<10; i++ {
  292. b.Write(buf)
  293. b.Read(buf)
  294. if i == 0 {
  295. cap0 = cap(b.buf)
  296. }
  297. }
  298. cap1 := cap(b.buf)
  299. // (*Buffer).grow allows for 2x capacity slop before sliding,
  300. // so set our error threshold at 3x.
  301. if cap1 > cap0*3 {
  302. t.Errorf("buffer cap = %d; too big (grew from %d)", cap1, cap0)
  303. }
  304. }
  305. // From Issue 5154.
  306. func BenchmarkBufferNotEmptyWriteRead(b *testing.B) {
  307. buf := make([]byte, 1024)
  308. for i := 0; i < b.N; i++ {
  309. var b Buffer
  310. b.Write(buf[0:1])
  311. for i := 0; i < 5<<10; i++ {
  312. b.Write(buf)
  313. b.Read(buf)
  314. }
  315. }
  316. }
  317. // Check that we don't compact too often. From Issue 5154.
  318. func BenchmarkBufferFullSmallReads(b *testing.B) {
  319. buf := make([]byte, 1024)
  320. for i := 0; i < b.N; i++ {
  321. var b Buffer
  322. b.Write(buf)
  323. for b.Len()+20 < cap(b.buf) {
  324. b.Write(buf[:10])
  325. }
  326. for i := 0; i < 5<<10; i++ {
  327. b.Read(buf[:1])
  328. b.Write(buf[:1])
  329. }
  330. }
  331. }