github.com/segmentio/kafka-go@v0.4.48-0.20240318174348-3f6244eb34fd/compress/snappy/go-xerial-snappy/snappy_test.go (about) 1 package snappy 2 3 import ( 4 "bytes" 5 "errors" 6 "testing" 7 ) 8 9 const largeString = `Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur? At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias except` 10 11 var snappyTestCases = map[string][]byte{ 12 "REPEATREPEATREPEATREPEATREPEATREPEAT": {36, 20, 82, 69, 80, 69, 65, 84, 118, 6, 0}, 13 "REALLY SHORT": {12, 44, 82, 69, 65, 76, 76, 89, 32, 83, 72, 79, 82, 84}, 14 "AXBXCXDXEXFX": {12, 44, 65, 88, 66, 88, 67, 88, 68, 88, 69, 88, 70, 88}, 15 } 16 17 var snappyStreamTestCases = map[string][]byte{ 18 "PLAINDATA": {130, 83, 78, 65, 80, 80, 89, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 11, 9, 32, 80, 76, 65, 73, 78, 68, 65, 84, 65}, 19 `{"a":"UtaitILHMDAAAAfU","b":"日本"}`: {130, 83, 78, 65, 80, 80, 89, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 39, 37, 144, 123, 34, 97, 34, 58, 34, 85, 116, 97, 105, 116, 73, 76, 72, 77, 68, 65, 65, 65, 65, 102, 85, 34, 44, 34, 98, 34, 58, 34, 230, 151, 165, 230, 156, 172, 34, 125}, 20 largeString: {130, 83, 78, 65, 80, 80, 89, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 3, 89, 128, 8, 240, 90, 83, 101, 100, 32, 117, 116, 32, 112, 101, 114, 115, 112, 105, 99, 105, 97, 116, 105, 115, 32, 117, 110, 100, 101, 32, 111, 109, 110, 105, 115, 32, 105, 115, 116, 101, 32, 110, 97, 116, 117, 115, 32, 101, 114, 114, 111, 114, 32, 115, 105, 116, 32, 118, 111, 108, 117, 112, 116, 97, 116, 101, 109, 32, 97, 99, 99, 117, 115, 97, 110, 116, 105, 117, 109, 32, 100, 111, 108, 111, 114, 101, 109, 113, 117, 101, 32, 108, 97, 117, 100, 97, 5, 22, 240, 60, 44, 32, 116, 111, 116, 97, 109, 32, 114, 101, 109, 32, 97, 112, 101, 114, 105, 97, 109, 44, 32, 101, 97, 113, 117, 101, 32, 105, 112, 115, 97, 32, 113, 117, 97, 101, 32, 97, 98, 32, 105, 108, 108, 111, 32, 105, 110, 118, 101, 110, 116, 111, 114, 101, 32, 118, 101, 114, 105, 116, 97, 1, 141, 4, 101, 116, 1, 36, 88, 115, 105, 32, 97, 114, 99, 104, 105, 116, 101, 99, 116, 111, 32, 98, 101, 97, 116, 97, 101, 32, 118, 105, 1, 6, 120, 100, 105, 99, 116, 97, 32, 115, 117, 110, 116, 32, 101, 120, 112, 108, 105, 99, 97, 98, 111, 46, 32, 78, 101, 109, 111, 32, 101, 110, 105, 109, 5, 103, 0, 109, 46, 180, 0, 12, 113, 117, 105, 97, 17, 16, 0, 115, 5, 209, 72, 97, 115, 112, 101, 114, 110, 97, 116, 117, 114, 32, 97, 117, 116, 32, 111, 100, 105, 116, 5, 9, 36, 102, 117, 103, 105, 116, 44, 32, 115, 101, 100, 9, 53, 32, 99, 111, 110, 115, 101, 113, 117, 117, 110, 1, 42, 20, 109, 97, 103, 110, 105, 32, 9, 245, 16, 115, 32, 101, 111, 115, 1, 36, 28, 32, 114, 97, 116, 105, 111, 110, 101, 17, 96, 33, 36, 1, 51, 36, 105, 32, 110, 101, 115, 99, 105, 117, 110, 116, 1, 155, 1, 254, 16, 112, 111, 114, 114, 111, 1, 51, 36, 115, 113, 117, 97, 109, 32, 101, 115, 116, 44, 1, 14, 13, 81, 5, 183, 4, 117, 109, 1, 18, 0, 97, 9, 19, 4, 32, 115, 1, 149, 12, 109, 101, 116, 44, 9, 135, 76, 99, 116, 101, 116, 117, 114, 44, 32, 97, 100, 105, 112, 105, 115, 99, 105, 32, 118, 101, 108, 50, 173, 0, 24, 110, 111, 110, 32, 110, 117, 109, 9, 94, 84, 105, 117, 115, 32, 109, 111, 100, 105, 32, 116, 101, 109, 112, 111, 114, 97, 32, 105, 110, 99, 105, 100, 33, 52, 20, 117, 116, 32, 108, 97, 98, 33, 116, 4, 101, 116, 9, 106, 0, 101, 5, 219, 20, 97, 109, 32, 97, 108, 105, 5, 62, 33, 164, 8, 114, 97, 116, 29, 212, 12, 46, 32, 85, 116, 41, 94, 52, 97, 100, 32, 109, 105, 110, 105, 109, 97, 32, 118, 101, 110, 105, 33, 221, 72, 113, 117, 105, 115, 32, 110, 111, 115, 116, 114, 117, 109, 32, 101, 120, 101, 114, 99, 105, 33, 202, 104, 111, 110, 101, 109, 32, 117, 108, 108, 97, 109, 32, 99, 111, 114, 112, 111, 114, 105, 115, 32, 115, 117, 115, 99, 105, 112, 105, 13, 130, 8, 105, 111, 115, 1, 64, 12, 110, 105, 115, 105, 1, 150, 5, 126, 44, 105, 100, 32, 101, 120, 32, 101, 97, 32, 99, 111, 109, 5, 192, 0, 99, 41, 131, 33, 172, 8, 63, 32, 81, 1, 107, 4, 97, 117, 33, 101, 96, 118, 101, 108, 32, 101, 117, 109, 32, 105, 117, 114, 101, 32, 114, 101, 112, 114, 101, 104, 101, 110, 100, 101, 114, 105, 65, 63, 12, 105, 32, 105, 110, 1, 69, 16, 118, 111, 108, 117, 112, 65, 185, 1, 47, 24, 105, 116, 32, 101, 115, 115, 101, 1, 222, 64, 109, 32, 110, 105, 104, 105, 108, 32, 109, 111, 108, 101, 115, 116, 105, 97, 101, 46, 103, 0, 0, 44, 1, 45, 16, 32, 105, 108, 108, 117, 37, 143, 45, 36, 0, 109, 5, 110, 65, 33, 20, 97, 116, 32, 113, 117, 111, 17, 92, 44, 115, 32, 110, 117, 108, 108, 97, 32, 112, 97, 114, 105, 9, 165, 24, 65, 116, 32, 118, 101, 114, 111, 69, 34, 44, 101, 116, 32, 97, 99, 99, 117, 115, 97, 109, 117, 115, 1, 13, 104, 105, 117, 115, 116, 111, 32, 111, 100, 105, 111, 32, 100, 105, 103, 110, 105, 115, 115, 105, 109, 111, 115, 32, 100, 117, 99, 105, 1, 34, 80, 113, 117, 105, 32, 98, 108, 97, 110, 100, 105, 116, 105, 105, 115, 32, 112, 114, 97, 101, 115, 101, 101, 87, 17, 111, 56, 116, 117, 109, 32, 100, 101, 108, 101, 110, 105, 116, 105, 32, 97, 116, 65, 89, 28, 99, 111, 114, 114, 117, 112, 116, 105, 1, 150, 0, 115, 13, 174, 5, 109, 8, 113, 117, 97, 65, 5, 52, 108, 101, 115, 116, 105, 97, 115, 32, 101, 120, 99, 101, 112, 116, 0, 0, 0, 1, 0}, 21 } 22 23 func makeMassive(input string, numCopies int) string { 24 outBuff := make([]byte, len(input)*numCopies) 25 26 for i := 0; i < numCopies; i++ { 27 copy(outBuff[len(outBuff):], input) 28 } 29 30 return string(outBuff) 31 } 32 33 func TestSnappyEncode(t *testing.T) { 34 for src, exp := range snappyTestCases { 35 dst := Encode([]byte(src)) 36 if !bytes.Equal(dst, exp) { 37 t.Errorf("Expected %s to generate %v, but was %v", src, exp, dst) 38 } 39 } 40 } 41 42 func TestSnappyEncodeStream(t *testing.T) { 43 for src := range snappyStreamTestCases { 44 dst := EncodeStream(nil, []byte(src)) 45 46 // Block size can change the bytes generated, so let's just decode and make sure in matches out 47 dec, err := Decode(dst) 48 if err != nil { 49 t.Error(err) 50 } 51 if src != string(dec) { 52 t.Errorf("Expected decode to match encode orig = %s, decoded = %s", src, string(dec)) 53 } 54 } 55 } 56 57 func TestSnappyLargeStringEncodeStream(t *testing.T) { 58 massiveString := makeMassive(largeString, 10000) 59 dst := EncodeStream(nil, []byte(massiveString)) 60 dec, err := Decode(dst) 61 if err != nil { 62 t.Error(err) 63 } 64 if massiveString != string(dec) { 65 t.Errorf("Decoded string didn't match original input (not printing due to size)") 66 } 67 } 68 69 func TestSnappyDecode(t *testing.T) { 70 for exp, src := range snappyTestCases { 71 dst, err := Decode(src) 72 if err != nil { 73 t.Error("Encoding error: ", err) 74 } else if !bytes.Equal(dst, []byte(exp)) { 75 t.Errorf("Expected %s to be generated from %v, but was %s", exp, src, string(dst)) 76 } 77 } 78 } 79 80 func TestSnappyDecodeStreams(t *testing.T) { 81 for exp, src := range snappyStreamTestCases { 82 dst, err := Decode(src) 83 if err != nil { 84 t.Error("Encoding error: ", err) 85 } else if !bytes.Equal(dst, []byte(exp)) { 86 t.Errorf("Expected %s to be generated from [%d]byte, but was %s", exp, len(src), string(dst)) 87 } 88 } 89 } 90 91 func TestSnappyDecodeMalformedTruncatedHeader(t *testing.T) { 92 // Truncated headers should not cause a panic. 93 for i := 0; i < len(xerialHeader); i++ { 94 buf := make([]byte, i) 95 copy(buf, xerialHeader[:i]) 96 if _, err := Decode(buf); !errors.Is(err, ErrMalformed) { 97 t.Errorf("expected ErrMalformed got %v", err) 98 } 99 } 100 } 101 102 func TestSnappyDecodeMalformedTruncatedSize(t *testing.T) { 103 // Inputs with valid Xerial header but truncated "size" field 104 sizes := []int{sizeOffset + 1, sizeOffset + 2, sizeOffset + 3} 105 for _, size := range sizes { 106 buf := make([]byte, size) 107 copy(buf, xerialHeader) 108 if _, err := Decode(buf); !errors.Is(err, ErrMalformed) { 109 t.Errorf("expected ErrMalformed got %v", err) 110 } 111 } 112 } 113 114 func TestSnappyDecodeMalformedBNoData(t *testing.T) { 115 // No data after the size field 116 buf := make([]byte, 20) 117 copy(buf, xerialHeader) 118 // indicate that there's one byte of data to be read 119 buf[len(buf)-1] = 1 120 if _, err := Decode(buf); !errors.Is(err, ErrMalformed) { 121 t.Errorf("expected ErrMalformed got %v", err) 122 } 123 } 124 125 func TestSnappyMasterDecodeFailed(t *testing.T) { 126 buf := make([]byte, 21) 127 copy(buf, xerialHeader) 128 // indicate that there's one byte of data to be read 129 buf[len(buf)-2] = 1 130 // A payload which will not decode 131 buf[len(buf)-1] = 1 132 if _, err := Decode(buf); errors.Is(err, ErrMalformed) || err == nil { 133 t.Errorf("unexpected err: %v", err) 134 } 135 } 136 137 func BenchmarkSnappyDecode(b *testing.B) { 138 b.ReportAllocs() 139 b.ResetTimer() 140 141 for n := 0; n < b.N; n++ { 142 bytes := 0 143 for _, test := range snappyTestCases { 144 dst, err := Decode(test) 145 if err != nil { 146 b.Error("Decoding error: ", err) 147 } 148 bytes += len(dst) 149 } 150 b.SetBytes(int64(bytes)) 151 } 152 } 153 154 func BenchmarkSnappyDecodeInto(b *testing.B) { 155 b.ReportAllocs() 156 b.ResetTimer() 157 158 var ( 159 dst []byte 160 err error 161 ) 162 163 for n := 0; n < b.N; n++ { 164 bytes := 0 165 for _, test := range snappyTestCases { 166 167 dst, err = DecodeInto(dst, test) 168 if err != nil { 169 b.Error("Decoding error: ", err) 170 } 171 bytes += len(dst) 172 } 173 b.SetBytes(int64(bytes)) 174 } 175 } 176 177 func BenchmarkSnappyStreamDecode(b *testing.B) { 178 b.ReportAllocs() 179 b.ResetTimer() 180 181 for n := 0; n < b.N; n++ { 182 bytes := 0 183 for _, test := range snappyStreamTestCases { 184 dst, err := Decode(test) 185 if err != nil { 186 b.Error("Decoding error: ", err) 187 } 188 bytes += len(dst) 189 } 190 b.SetBytes(int64(bytes)) 191 } 192 } 193 194 func BenchmarkSnappyStreamDecodeInto(b *testing.B) { 195 b.ReportAllocs() 196 b.ResetTimer() 197 198 var ( 199 dst = make([]byte, 1024) 200 err error 201 ) 202 203 for n := 0; n < b.N; n++ { 204 bytes := 0 205 for _, test := range snappyStreamTestCases { 206 dst, err = DecodeInto(dst, test) 207 if err != nil { 208 b.Error("Decoding error: ", err) 209 } 210 bytes += len(dst) 211 } 212 b.SetBytes(int64(bytes)) 213 } 214 } 215 func BenchmarkSnappyStreamDecodeMassive(b *testing.B) { 216 massiveString := makeMassive(largeString, 10000) 217 enc := EncodeStream(nil, []byte(massiveString)) 218 219 b.ReportAllocs() 220 b.ResetTimer() 221 b.SetBytes(int64(len(massiveString))) 222 223 for n := 0; n < b.N; n++ { 224 _, err := Decode(enc) 225 if err != nil { 226 b.Error("Decoding error: ", err) 227 } 228 } 229 } 230 231 func BenchmarkSnappyStreamDecodeIntoMassive(b *testing.B) { 232 massiveString := makeMassive(largeString, 10000) 233 enc := EncodeStream(nil, []byte(massiveString)) 234 235 b.ReportAllocs() 236 b.ResetTimer() 237 b.SetBytes(int64(len(massiveString))) 238 239 var ( 240 dst = make([]byte, 1024) 241 err error 242 ) 243 244 for n := 0; n < b.N; n++ { 245 dst, err = DecodeInto(dst, enc) 246 if err != nil { 247 b.Error("Decoding error: ", err) 248 } 249 } 250 }