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  }