github.com/masterhung0112/hk_server/v5@v5.0.0-20220302090640-ec71aef15e1c/app/imaging/decode_test.go (about) 1 // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. 2 // See LICENSE.txt for license information. 3 4 package imaging 5 6 import ( 7 "bytes" 8 "os" 9 "sync" 10 "testing" 11 12 "github.com/masterhung0112/hk_server/v5/utils/fileutils" 13 14 "github.com/stretchr/testify/require" 15 ) 16 17 func TestNewDecoder(t *testing.T) { 18 t.Run("invalid options", func(t *testing.T) { 19 d, err := NewDecoder(DecoderOptions{ 20 ConcurrencyLevel: -1, 21 }) 22 require.Nil(t, d) 23 require.Error(t, err) 24 }) 25 26 t.Run("empty options", func(t *testing.T) { 27 d, err := NewDecoder(DecoderOptions{}) 28 require.NotNil(t, d) 29 require.NoError(t, err) 30 require.Nil(t, d.sem) 31 }) 32 33 t.Run("valid options", func(t *testing.T) { 34 d, err := NewDecoder(DecoderOptions{ 35 ConcurrencyLevel: 4, 36 }) 37 require.NotNil(t, d) 38 require.NoError(t, err) 39 require.NotNil(t, d.sem) 40 require.Equal(t, 4, cap(d.sem)) 41 }) 42 } 43 44 func TestDecoderDecode(t *testing.T) { 45 t.Run("default options", func(t *testing.T) { 46 d, err := NewDecoder(DecoderOptions{}) 47 require.NotNil(t, d) 48 require.NoError(t, err) 49 50 imgDir, ok := fileutils.FindDir("tests") 51 require.True(t, ok) 52 53 imgFile, err := os.Open(imgDir + "/test.png") 54 require.NoError(t, err) 55 require.NotNil(t, imgFile) 56 defer imgFile.Close() 57 58 img, format, err := d.Decode(imgFile) 59 require.NoError(t, err) 60 require.NotNil(t, img) 61 require.Equal(t, "png", format) 62 }) 63 64 t.Run("concurrency bounded", func(t *testing.T) { 65 d, err := NewDecoder(DecoderOptions{ 66 ConcurrencyLevel: 1, 67 }) 68 require.NotNil(t, d) 69 require.NoError(t, err) 70 71 imgDir, ok := fileutils.FindDir("tests") 72 require.True(t, ok) 73 74 var wg sync.WaitGroup 75 wg.Add(2) 76 77 go func() { 78 defer wg.Done() 79 80 imgFile, err := os.Open(imgDir + "/test.png") 81 require.NoError(t, err) 82 require.NotNil(t, imgFile) 83 defer imgFile.Close() 84 85 img, format, err := d.Decode(imgFile) 86 require.NoError(t, err) 87 require.NotNil(t, img) 88 require.Equal(t, "png", format) 89 }() 90 91 go func() { 92 defer wg.Done() 93 94 imgFile, err := os.Open(imgDir + "/test.png") 95 require.NoError(t, err) 96 require.NotNil(t, imgFile) 97 defer imgFile.Close() 98 99 img, format, err := d.Decode(imgFile) 100 require.NoError(t, err) 101 require.NotNil(t, img) 102 require.Equal(t, "png", format) 103 }() 104 105 wg.Wait() 106 require.Empty(t, d.sem) 107 }) 108 } 109 110 func TestDecoderDecodeMemBounded(t *testing.T) { 111 t.Run("concurrency bounded", func(t *testing.T) { 112 d, err := NewDecoder(DecoderOptions{ 113 ConcurrencyLevel: 1, 114 }) 115 require.NotNil(t, d) 116 require.NoError(t, err) 117 118 imgDir, ok := fileutils.FindDir("tests") 119 require.True(t, ok) 120 121 imgFile, err := os.Open(imgDir + "/test.png") 122 require.NoError(t, err) 123 require.NotNil(t, imgFile) 124 defer imgFile.Close() 125 126 var wg sync.WaitGroup 127 wg.Add(2) 128 129 var lock sync.Mutex 130 131 go func() { 132 defer wg.Done() 133 img, format, release, err := d.DecodeMemBounded(imgFile) 134 lock.Lock() 135 imgFile.Seek(0, 0) 136 lock.Unlock() 137 require.NoError(t, err) 138 defer release() 139 require.NotNil(t, img) 140 require.Equal(t, "png", format) 141 require.NotNil(t, release) 142 require.NotEmpty(t, d.sem) 143 }() 144 145 go func() { 146 defer wg.Done() 147 img, format, release, err := d.DecodeMemBounded(imgFile) 148 lock.Lock() 149 imgFile.Seek(0, 0) 150 lock.Unlock() 151 require.NoError(t, err) 152 defer release() 153 require.NotNil(t, img) 154 require.Equal(t, "png", format) 155 require.NotNil(t, release) 156 require.NotEmpty(t, d.sem) 157 }() 158 159 wg.Wait() 160 require.Empty(t, d.sem) 161 }) 162 163 t.Run("decode error", func(t *testing.T) { 164 d, err := NewDecoder(DecoderOptions{ 165 ConcurrencyLevel: 1, 166 }) 167 require.NotNil(t, d) 168 require.NoError(t, err) 169 170 var data bytes.Buffer 171 172 var wg sync.WaitGroup 173 wg.Add(2) 174 175 go func() { 176 defer wg.Done() 177 img, format, release, err := d.DecodeMemBounded(&data) 178 require.Error(t, err) 179 require.Nil(t, img) 180 require.Empty(t, format) 181 require.Nil(t, release) 182 }() 183 184 go func() { 185 defer wg.Done() 186 img, format, release, err := d.DecodeMemBounded(&data) 187 require.Error(t, err) 188 require.Nil(t, img) 189 require.Empty(t, format) 190 require.Nil(t, release) 191 }() 192 193 wg.Wait() 194 require.Empty(t, d.sem) 195 }) 196 197 t.Run("multiple releases", func(t *testing.T) { 198 d, err := NewDecoder(DecoderOptions{ 199 ConcurrencyLevel: 1, 200 }) 201 require.NotNil(t, d) 202 require.NoError(t, err) 203 204 imgDir, ok := fileutils.FindDir("tests") 205 require.True(t, ok) 206 207 imgFile, err := os.Open(imgDir + "/test.png") 208 require.NoError(t, err) 209 require.NotNil(t, imgFile) 210 defer imgFile.Close() 211 212 img, format, release, err := d.DecodeMemBounded(imgFile) 213 require.NoError(t, err) 214 require.NotNil(t, img) 215 require.Equal(t, "png", format) 216 require.NotNil(t, release) 217 require.Len(t, d.sem, 1) 218 release() 219 require.Empty(t, d.sem) 220 release() 221 require.Empty(t, d.sem) 222 release() 223 require.Empty(t, d.sem) 224 }) 225 }