github.com/tsuna/gohbase@v0.0.0-20250731002811-4ffcadfba63e/compression/snappy/snappy_test.go (about) 1 // Copyright (C) 2020 The GoHBase Authors. All rights reserved. 2 // This file is part of GoHBase. 3 // Use of this source code is governed by the Apache License 2.0 4 // that can be found in the COPYING file. 5 6 package snappy_test 7 8 import ( 9 "bytes" 10 "errors" 11 "reflect" 12 "strconv" 13 "testing" 14 "unsafe" 15 16 "github.com/tsuna/gohbase/compression" 17 "github.com/tsuna/gohbase/compression/snappy" 18 "github.com/tsuna/gohbase/test" 19 ) 20 21 func TestEncode(t *testing.T) { 22 tests := []struct { 23 src []byte 24 dst []byte 25 out []byte 26 sz uint32 27 sameAsDst bool 28 }{ 29 { 30 dst: nil, 31 src: []byte("test"), 32 out: []byte("\x04\ftest"), 33 sz: 6, 34 }, 35 { 36 src: nil, 37 out: []byte("\x00"), 38 sz: 1, 39 }, 40 { 41 src: []byte("test"), 42 dst: []byte("something here already"), 43 out: []byte("something here already\x04\ftest"), 44 sz: 6, 45 }, 46 { 47 src: []byte("test"), 48 dst: make([]byte, 4, 10), 49 out: []byte("\x00\x00\x00\x00\x04\ftest"), 50 sz: 6, 51 sameAsDst: true, 52 }, 53 { 54 src: []byte("test"), 55 dst: make([]byte, 4, 11), 56 out: []byte("\x00\x00\x00\x00\x04\ftest"), 57 sz: 6, 58 sameAsDst: true, 59 }, 60 { 61 src: []byte("test"), 62 dst: make([]byte, 4, 9), 63 out: []byte("\x00\x00\x00\x00\x04\ftest"), 64 sz: 6, 65 sameAsDst: false, 66 }, 67 } 68 69 for i, tcase := range tests { 70 t.Run(strconv.Itoa(i), func(t *testing.T) { 71 var codec compression.Codec 72 codec = snappy.New() 73 74 dst := make([]byte, len(tcase.dst), cap(tcase.dst)) 75 copy(dst, tcase.dst) 76 dstHeader := (*reflect.SliceHeader)(unsafe.Pointer(&dst)) 77 78 out, sz := codec.Encode(tcase.src, dst) 79 80 if tcase.sz != sz { 81 t.Errorf("expected size %d, got %d", tcase.sz, sz) 82 } 83 84 if l := len(tcase.dst) + int(sz); l != len(out) { 85 t.Errorf("expected length %d, got %d", l, len(out)) 86 } 87 88 if !bytes.Equal(tcase.out, out) { 89 t.Errorf("expected out %q, got %q", tcase.out, out) 90 } 91 92 outHeader := (*reflect.SliceHeader)(unsafe.Pointer(&out)) 93 if tcase.sameAsDst && dstHeader.Data != outHeader.Data { 94 t.Errorf("expected dst %v to be reused, got %v", dstHeader, outHeader) 95 } 96 }) 97 } 98 } 99 100 func TestDecode(t *testing.T) { 101 tests := []struct { 102 src []byte 103 dst []byte 104 out []byte 105 sz uint32 106 err error 107 sameAsDst bool 108 }{ 109 { 110 src: []byte("\x04\ftest"), 111 out: []byte("test"), 112 sz: 4, 113 }, 114 { 115 src: []byte("\x00"), 116 out: nil, 117 sz: 0, 118 }, 119 { 120 src: []byte("\x04\ftest"), 121 dst: []byte("something here already"), 122 out: []byte("something here alreadytest"), 123 sz: 4, 124 }, 125 { 126 src: []byte("\x04\ftest"), 127 dst: make([]byte, 4, 8), 128 out: []byte("\x00\x00\x00\x00test"), 129 sz: 4, 130 sameAsDst: true, 131 }, 132 { 133 src: []byte("\x04\ftest"), 134 dst: make([]byte, 4, 9), 135 out: []byte("\x00\x00\x00\x00test"), 136 sz: 4, 137 sameAsDst: true, 138 }, 139 { 140 src: []byte("\x04\ftest"), 141 dst: make([]byte, 4, 7), 142 out: []byte("\x00\x00\x00\x00test"), 143 sz: 4, 144 sameAsDst: false, 145 }, 146 { 147 src: []byte("test"), 148 err: errors.New("snappy: corrupt input"), 149 }, 150 { 151 src: []byte("\x04\ftes"), 152 err: errors.New("snappy: corrupt input"), 153 }, 154 { 155 src: []byte("\x04\ftestasdfasdfasdf"), 156 err: errors.New("snappy: corrupt input"), 157 }, 158 } 159 160 for i, tcase := range tests { 161 t.Run(strconv.Itoa(i), func(t *testing.T) { 162 var codec compression.Codec 163 codec = snappy.New() 164 165 dst := make([]byte, len(tcase.dst), cap(tcase.dst)) 166 copy(dst, tcase.dst) 167 dstHeader := (*reflect.SliceHeader)(unsafe.Pointer(&dst)) 168 169 out, sz, err := codec.Decode(tcase.src, dst) 170 171 if !test.ErrEqual(tcase.err, err) { 172 t.Errorf("expected error %v, got %v", tcase.err, err) 173 } 174 175 if tcase.sz != sz { 176 t.Errorf("expected size %d, got %d", tcase.sz, sz) 177 } 178 179 if l := len(tcase.dst) + int(sz); l != len(out) { 180 t.Errorf("expected length %d, got %d", l, len(out)) 181 } 182 183 if !bytes.Equal(tcase.out, out) { 184 t.Errorf("expected out %q, got %q", tcase.out, out) 185 } 186 187 outHeader := (*reflect.SliceHeader)(unsafe.Pointer(&out)) 188 if tcase.sameAsDst && dstHeader.Data != outHeader.Data { 189 t.Errorf("expected dst %v to be reused, got %v", dstHeader, outHeader) 190 } 191 }) 192 } 193 }