github.com/voedger/voedger@v0.0.0-20240520144910-273e84102129/pkg/iblobstoragestg/impl_test.go (about)

     1  /*
     2   * Copyright (c) 2021-present Sigma-Soft, Ltd.
     3   */
     4  
     5  package iblobstoragestg
     6  
     7  import (
     8  	"bufio"
     9  	"bytes"
    10  	"context"
    11  	_ "embed"
    12  	"io"
    13  	"log"
    14  	"testing"
    15  	"time"
    16  
    17  	"github.com/stretchr/testify/require"
    18  
    19  	"github.com/voedger/voedger/pkg/iblobstorage"
    20  	"github.com/voedger/voedger/pkg/istorage/mem"
    21  	istorageimpl "github.com/voedger/voedger/pkg/istorage/provider"
    22  	"github.com/voedger/voedger/pkg/istructs"
    23  )
    24  
    25  var (
    26  	//go:embed logo.png
    27  	blob    []byte
    28  	maxSize int64 = 19266
    29  )
    30  
    31  func TestBasicUsage(t *testing.T) {
    32  	var (
    33  		key = iblobstorage.KeyType{
    34  			AppID: 2,
    35  			WSID:  2,
    36  			ID:    2,
    37  		}
    38  		desc = iblobstorage.DescrType{
    39  			Name:     "logo.png",
    40  			MimeType: "image/png",
    41  		}
    42  	)
    43  	require := require.New(t)
    44  
    45  	asf := mem.Provide()
    46  	asp := istorageimpl.Provide(asf)
    47  	storage, err := asp.AppStorage(istructs.AppQName_test1_app1)
    48  	require.NoError(err)
    49  	blobber := Provide(&storage, time.Now)
    50  	ctx := context.TODO()
    51  	reader := provideTestData()
    52  
    53  	t.Run("Read blob that is absent. We MUST get error iblobstorage.ErrBLOBNotFound.", func(t *testing.T) {
    54  		var (
    55  			buf   bytes.Buffer
    56  			state iblobstorage.BLOBState
    57  		)
    58  		writer := bufio.NewWriter(&buf)
    59  		err := blobber.ReadBLOB(ctx, key, func(blobState iblobstorage.BLOBState) (err error) {
    60  			state = blobState
    61  			require.Nil(state)
    62  			return nil
    63  		}, writer)
    64  		require.ErrorIs(err, iblobstorage.ErrBLOBNotFound)
    65  	})
    66  
    67  	t.Run("Write blob to storage, return must be without errors", func(t *testing.T) {
    68  		err := blobber.WriteBLOB(ctx, key, desc, reader, maxSize)
    69  		require.NoError(err)
    70  	})
    71  
    72  	t.Run("Read blob status, return must be without errors", func(t *testing.T) {
    73  		bs, err := blobber.QueryBLOBState(ctx, key)
    74  		require.NoError(err)
    75  		require.Equal(iblobstorage.BLOBStatus_Completed, bs.Status)
    76  	})
    77  
    78  	t.Run("Read blob that present in storage and compare with reference", func(t *testing.T) {
    79  		var (
    80  			buf   bytes.Buffer
    81  			state iblobstorage.BLOBState
    82  		)
    83  		writer := bufio.NewWriter(&buf)
    84  
    85  		// Reset reader and read anew
    86  		reader.Reset(blob)
    87  		v, err := readData(ctx, reader)
    88  		require.NoError(err)
    89  
    90  		// Read
    91  		err = blobber.ReadBLOB(ctx, key, func(blobState iblobstorage.BLOBState) (err error) {
    92  			state = blobState
    93  			log.Println(state.Error)
    94  			return nil
    95  		}, writer)
    96  
    97  		require.NoError(err)
    98  		err = writer.Flush()
    99  		require.NoError(err)
   100  
   101  		// Compare
   102  		require.Equal(v, buf.Bytes())
   103  	})
   104  }
   105  
   106  func TestQuotaExceed(t *testing.T) {
   107  	var (
   108  		key = iblobstorage.KeyType{
   109  			AppID: 2,
   110  			WSID:  2,
   111  			ID:    2,
   112  		}
   113  		desc = iblobstorage.DescrType{
   114  			Name:     "logo.png",
   115  			MimeType: "image/png",
   116  		}
   117  	)
   118  	require := require.New(t)
   119  	asf := mem.Provide()
   120  	asp := istorageimpl.Provide(asf)
   121  	storage, err := asp.AppStorage(istructs.AppQName_test1_app1)
   122  	require.NoError(err)
   123  	blobber := Provide(&storage, time.Now)
   124  	reader := provideTestData()
   125  	ctx := context.Background()
   126  	// Quota (maxSize -1 = 19265) assigned to reader less then filesize logo.png (maxSize)
   127  	// So, it must be error
   128  	err = blobber.WriteBLOB(ctx, key, desc, reader, maxSize-1)
   129  	require.Error(err, "Reading a file larger than the quota assigned to the reader. It must be a error.")
   130  }
   131  
   132  func provideTestData() (reader *bytes.Reader) {
   133  	return bytes.NewReader(blob)
   134  }
   135  
   136  func readData(ctx context.Context, reader io.Reader) (data []byte, err error) {
   137  	var bytesRead int
   138  	var entity []byte
   139  	nBytes := int64(0)
   140  	buf := make([]byte, 0, chunkSize)
   141  	for err == nil {
   142  		if ctx.Err() != nil {
   143  			return nil, ctx.Err()
   144  		}
   145  		bytesRead, err = reader.Read(buf[:cap(buf)])
   146  		if bytesRead > 0 {
   147  			buf = buf[:bytesRead]
   148  			nBytes += int64(len(buf))
   149  			entity = append(entity, buf...)
   150  		}
   151  	}
   152  	if err == io.EOF {
   153  		err = nil
   154  	}
   155  	return entity, err
   156  }