github.com/ydb-platform/ydb-go-sdk/v3@v3.57.0/internal/topic/topicwriterinternal/encoders_test.go (about)

     1  package topicwriterinternal
     2  
     3  import (
     4  	"bytes"
     5  	"strings"
     6  	"testing"
     7  
     8  	"github.com/stretchr/testify/require"
     9  
    10  	"github.com/ydb-platform/ydb-go-sdk/v3/internal/grpcwrapper/rawtopic/rawtopiccommon"
    11  	"github.com/ydb-platform/ydb-go-sdk/v3/internal/xrand"
    12  	"github.com/ydb-platform/ydb-go-sdk/v3/trace"
    13  )
    14  
    15  func TestEncoderSelector_CodecMeasure(t *testing.T) {
    16  	t.Run("Empty", func(t *testing.T) {
    17  		s := NewEncoderSelector(testCommonEncoders, nil, 1, &trace.Topic{}, "", "")
    18  		_, err := s.measureCodecs(nil)
    19  		require.Error(t, err)
    20  	})
    21  	t.Run("One", func(t *testing.T) {
    22  		s := NewEncoderSelector(
    23  			NewEncoderMap(),
    24  			rawtopiccommon.SupportedCodecs{rawtopiccommon.CodecRaw},
    25  			1,
    26  			&trace.Topic{},
    27  			"",
    28  			"",
    29  		)
    30  		codec, err := s.measureCodecs(nil)
    31  		require.NoError(t, err)
    32  		require.Equal(t, rawtopiccommon.CodecRaw, codec)
    33  	})
    34  
    35  	t.Run("SelectCodecByMeasure", func(t *testing.T) {
    36  		// for reproducible result between runs
    37  		r := xrand.New(xrand.WithSeed(0))
    38  		const (
    39  			smallSize = 1
    40  			largeSize = 100
    41  		)
    42  
    43  		testSelectCodec := func(t testing.TB, targetCodec rawtopiccommon.Codec, smallCount, largeCount int) {
    44  			s := NewEncoderSelector(testCommonEncoders, rawtopiccommon.SupportedCodecs{
    45  				rawtopiccommon.CodecRaw,
    46  				rawtopiccommon.CodecGzip,
    47  			}, 4,
    48  				&trace.Topic{}, "", "",
    49  			)
    50  
    51  			var messages []messageWithDataContent
    52  			for i := 0; i < smallCount; i++ {
    53  				data := make([]byte, smallSize)
    54  				message := newMessageDataWithContent(PublicMessage{Data: bytes.NewReader(data)}, testCommonEncoders)
    55  				messages = append(messages, message)
    56  			}
    57  
    58  			for i := 0; i < largeCount; i++ {
    59  				data := make([]byte, largeSize)
    60  				message := newMessageDataWithContent(PublicMessage{Data: bytes.NewReader(data)}, testCommonEncoders)
    61  				messages = append(messages, message)
    62  			}
    63  
    64  			codec, err := s.measureCodecs(messages)
    65  			require.NoError(t, err)
    66  			require.Equal(t, targetCodec, codec)
    67  
    68  			// reverse
    69  			{
    70  				reverseMessages := make([]messageWithDataContent, len(messages))
    71  				for index := range messages {
    72  					reverseMessages[index] = messages[len(messages)-index-1]
    73  				}
    74  				messages = reverseMessages
    75  			}
    76  			codec, err = s.measureCodecs(messages)
    77  			require.NoError(t, err)
    78  			require.Equal(t, targetCodec, codec)
    79  
    80  			// shuffle
    81  			r.Shuffle(len(messages), func(i, k int) {
    82  				messages[i], messages[k] = messages[k], messages[i]
    83  			})
    84  			codec, err = s.measureCodecs(messages)
    85  			require.NoError(t, err)
    86  			require.Equal(t, targetCodec, codec)
    87  		}
    88  
    89  		table := []struct {
    90  			name        string
    91  			smallCount  int
    92  			largeCount  int
    93  			targetCodec rawtopiccommon.Codec
    94  		}{
    95  			{
    96  				"OneSmall",
    97  				1,
    98  				0,
    99  				rawtopiccommon.CodecRaw,
   100  			},
   101  			{
   102  				"ManySmall",
   103  				10,
   104  				0,
   105  				rawtopiccommon.CodecRaw,
   106  			},
   107  			{
   108  				"OneLarge",
   109  				0,
   110  				1,
   111  				rawtopiccommon.CodecGzip,
   112  			},
   113  			{
   114  				"ManyLarge",
   115  				0,
   116  				1,
   117  				rawtopiccommon.CodecGzip,
   118  			},
   119  			{
   120  				"OneSmallOneLarge",
   121  				1,
   122  				1,
   123  				rawtopiccommon.CodecGzip,
   124  			},
   125  			{
   126  				"ManySmallOneLarge",
   127  				100,
   128  				1,
   129  				rawtopiccommon.CodecRaw,
   130  			},
   131  			{
   132  				"OneSmallManyLarge",
   133  				1,
   134  				10,
   135  				rawtopiccommon.CodecGzip,
   136  			},
   137  			{
   138  				"ManySmallManyLarge",
   139  				10,
   140  				10,
   141  				rawtopiccommon.CodecGzip,
   142  			},
   143  		}
   144  
   145  		for _, test := range table {
   146  			t.Run(test.name, func(t *testing.T) {
   147  				testSelectCodec(t, test.targetCodec, test.smallCount, test.largeCount)
   148  			})
   149  		}
   150  	})
   151  }
   152  
   153  func TestCompressMessages(t *testing.T) {
   154  	t.Run("NoMessages", func(t *testing.T) {
   155  		require.NoError(t, cacheMessages(nil, rawtopiccommon.CodecRaw, 1))
   156  	})
   157  
   158  	t.Run("RawOk", func(t *testing.T) {
   159  		messages := newTestMessagesWithContent(1)
   160  		require.NoError(t, cacheMessages(messages, rawtopiccommon.CodecRaw, 1))
   161  	})
   162  	t.Run("RawError", func(t *testing.T) {
   163  		mess := newMessageDataWithContent(PublicMessage{}, testCommonEncoders)
   164  		_, err := mess.GetEncodedBytes(rawtopiccommon.CodecGzip)
   165  		require.NoError(t, err)
   166  		messages := []messageWithDataContent{mess}
   167  		require.Error(t, cacheMessages(messages, rawtopiccommon.CodecRaw, 1))
   168  	})
   169  
   170  	const messageCount = 10
   171  	t.Run("GzipOneThread", func(t *testing.T) {
   172  		var messages []messageWithDataContent
   173  		for i := 0; i < messageCount; i++ {
   174  			mess := newMessageDataWithContent(PublicMessage{Data: strings.NewReader("asdf")}, testCommonEncoders)
   175  			messages = append(messages, mess)
   176  		}
   177  
   178  		require.NoError(t, cacheMessages(messages, rawtopiccommon.CodecGzip, 1))
   179  		for i := 0; i < messageCount; i++ {
   180  			require.Equal(t, rawtopiccommon.CodecGzip, messages[i].bufCodec)
   181  		}
   182  	})
   183  
   184  	const parallelCount = 10
   185  	t.Run("GzipOk", func(t *testing.T) {
   186  		var messages []messageWithDataContent
   187  		for i := 0; i < messageCount; i++ {
   188  			mess := newMessageDataWithContent(PublicMessage{Data: strings.NewReader("asdf")}, testCommonEncoders)
   189  			messages = append(messages, mess)
   190  		}
   191  
   192  		require.NoError(t, cacheMessages(messages, rawtopiccommon.CodecGzip, parallelCount))
   193  		for i := 0; i < messageCount; i++ {
   194  			require.Equal(t, rawtopiccommon.CodecGzip, messages[i].bufCodec)
   195  		}
   196  	})
   197  
   198  	t.Run("GzipErr", func(t *testing.T) {
   199  		var messages []messageWithDataContent
   200  		for i := 0; i < messageCount; i++ {
   201  			mess := newMessageDataWithContent(PublicMessage{Data: strings.NewReader("asdf")}, testCommonEncoders)
   202  			messages = append(messages, mess)
   203  		}
   204  		messages[0].dataWasRead = true
   205  
   206  		require.Error(t, cacheMessages(messages, rawtopiccommon.CodecGzip, parallelCount))
   207  	})
   208  }