skipReader_test.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. package obfuscator
  2. import (
  3. "bytes"
  4. "io"
  5. "strings"
  6. "testing"
  7. )
  8. func TestReadBuffer(t *testing.T) {
  9. t.Parallel()
  10. type test struct {
  11. name string
  12. prefix []byte
  13. terminator []byte
  14. postfix []byte
  15. readSize int
  16. expectedErrStr string
  17. }
  18. tests := []test{
  19. {
  20. name: "1 byte terminnator at start",
  21. prefix: []byte{},
  22. terminator: []byte{'a'},
  23. postfix: []byte("postfix"),
  24. readSize: 1024,
  25. },
  26. {
  27. name: "no prefix",
  28. prefix: []byte{},
  29. terminator: []byte("[terminator]"),
  30. postfix: []byte("postfix"),
  31. readSize: 1,
  32. },
  33. {
  34. name: "small prefix",
  35. prefix: []byte("prefix"),
  36. terminator: []byte("[terminator]"),
  37. postfix: []byte("postfix"),
  38. readSize: 1,
  39. },
  40. {
  41. name: "large prefix",
  42. prefix: []byte(strings.Repeat("prefix", 1000)),
  43. terminator: []byte("[terminator]"),
  44. postfix: []byte("postfix"),
  45. readSize: 1,
  46. },
  47. {
  48. name: "large read size",
  49. prefix: []byte(strings.Repeat("prefix", 1000)),
  50. terminator: []byte("[terminator]"),
  51. postfix: []byte("postfix"),
  52. readSize: 8192,
  53. },
  54. {
  55. name: "max prefix size",
  56. prefix: bytes.Repeat([]byte{'a'}, PREFIX_MAX_LENGTH),
  57. terminator: []byte("[terminator]"),
  58. postfix: []byte{},
  59. readSize: 8192,
  60. expectedErrStr: "",
  61. },
  62. {
  63. name: "exceed max prefix length",
  64. prefix: bytes.Repeat([]byte{'a'}, PREFIX_MAX_LENGTH+1),
  65. terminator: []byte("[terminator]"),
  66. postfix: []byte{},
  67. readSize: 8192,
  68. expectedErrStr: "exceeded max search size",
  69. },
  70. }
  71. for _, tt := range tests {
  72. t.Run(tt.name, func(t *testing.T) {
  73. conn := newConn(append(tt.prefix, append(tt.terminator, tt.postfix...)...))
  74. reader, _ := WrapConnWithSkipReader(conn).(*SkipReader)
  75. defer reader.Close()
  76. err := reader.SkipUpToToken(
  77. tt.terminator, tt.readSize, PREFIX_MAX_LENGTH+len(tt.terminator))
  78. if tt.expectedErrStr != "" {
  79. if err == nil {
  80. t.Fatalf("SkipUpToToken returned nil error, expected %s", tt.expectedErrStr)
  81. } else if !strings.Contains(err.Error(), tt.expectedErrStr) {
  82. t.Fatalf("SkipUpToToken returned error %s, expected %s", err, tt.expectedErrStr)
  83. } else {
  84. return
  85. }
  86. }
  87. if err != nil {
  88. t.Fatalf("SkipUpToToken returned unexpected error: %s", err)
  89. }
  90. // read the rest one byte at a time
  91. var buff bytes.Buffer
  92. for {
  93. b := make([]byte, 1)
  94. _, err := reader.Read(b)
  95. if err != nil {
  96. if err == io.EOF {
  97. break
  98. }
  99. t.Fatal(err)
  100. }
  101. buff.Write(b)
  102. }
  103. if !bytes.Equal(buff.Bytes(), tt.postfix) {
  104. t.Fatalf("Read returned %v, expected %v", buff.Bytes(), tt.postfix)
  105. }
  106. })
  107. }
  108. }
  109. func BenchmarkBase(b *testing.B) {
  110. data := make([]byte, 1024*1024)
  111. for i := 0; i < len(data); i++ {
  112. data[i] = byte(i % 256)
  113. }
  114. terminator := []byte("[terminator]postfix")
  115. copy(data[len(data)-len(terminator):], terminator)
  116. b.ResetTimer()
  117. idx := bytes.Index(data, []byte("[terminator]"))
  118. if idx == -1 {
  119. b.Fatal("terminator not found")
  120. }
  121. if idx != len(data)-len(terminator) {
  122. b.Fatalf("terminator not at expected position: %d", idx)
  123. }
  124. }
  125. func BenchmarkSkipReader(b *testing.B) {
  126. data := make([]byte, 1024*1024)
  127. for i := 0; i < len(data); i++ {
  128. data[i] = byte(i % 256)
  129. }
  130. tail := []byte("[terminator]postfix")
  131. copy(data[len(data)-len(tail):], tail)
  132. conn := newConn(data)
  133. reader, _ := WrapConnWithSkipReader(conn).(*SkipReader)
  134. defer reader.Close()
  135. b.ResetTimer()
  136. err := reader.SkipUpToToken([]byte("[terminator]"), 1024, 1024*1024*1024)
  137. if err != nil {
  138. b.Fatalf("SkipUpToToken failed: %s", err)
  139. }
  140. b.StopTimer()
  141. // read the rest
  142. rest, err := io.ReadAll(reader)
  143. if err != nil {
  144. b.Fatal(err)
  145. }
  146. if string(rest) != "postfix" {
  147. b.Fatalf("Read returned %s, expected 'postfix'", rest)
  148. }
  149. }