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 }