diff --git a/config/configcompression/compressiontype.go b/config/configcompression/compressiontype.go index 820c85be983..53c5030e81c 100644 --- a/config/configcompression/compressiontype.go +++ b/config/configcompression/compressiontype.go @@ -47,6 +47,9 @@ func (ct *Type) UnmarshalText(in []byte) error { } // IsZstd returns true if the compression type is zstd. +// The specified compression level is not validated. +// Because zstd supports returning an encoder level that closest matches the compression ratio of a specific zstd compression level. +// Many input values will provide the same compression level. func (ct *Type) IsZstd() bool { parts := strings.Split(string(*ct), "/") return parts[0] == string(TypeZstd) @@ -68,6 +71,7 @@ func (ct *Type) IsGzip() bool { levelStr == zlib.NoCompression { return true } + return false } return true } @@ -90,6 +94,7 @@ func (ct *Type) IsZlib() bool { levelStr == zlib.NoCompression { return true } + return false } return true } diff --git a/config/configcompression/compressiontype_test.go b/config/configcompression/compressiontype_test.go index cf8166d5a24..0fc7c3e8a40 100644 --- a/config/configcompression/compressiontype_test.go +++ b/config/configcompression/compressiontype_test.go @@ -78,3 +78,116 @@ func TestUnmarshalText(t *testing.T) { }) } } + +func TestIsZstd(t *testing.T) { + tests := []struct { + name string + input Type + expected bool + }{ + { + name: "ValidZstd", + input: TypeZstd, + expected: true, + }, + { + name: "InvalidZstd", + input: TypeGzip, + expected: false, + }, + { + name: "ValidZstdLevel", + input: "zstd/11", + expected: true, + }, + { + name: "ValidZstdLevel", + input: "zstd/One", + expected: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equal(t, tt.expected, tt.input.IsZstd()) + }) + } +} + +func TestIsGzip(t *testing.T) { + tests := []struct { + name string + input Type + expected bool + }{ + { + name: "ValidGzip", + input: TypeGzip, + expected: true, + }, + { + name: "InvalidGzip", + input: TypeZlib, + expected: false, + }, + { + name: "ValidZlibCompressionLevel", + input: "gzip/1", + expected: true, + }, + { + name: "InvalidZlibCompressionLevel", + input: "gzip/10", + expected: false, + }, + { + name: "InvalidZlibCompressionLevel", + input: "gzip/one", + expected: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equal(t, tt.expected, tt.input.IsGzip()) + }) + } +} + +func TestIsZlib(t *testing.T) { + tests := []struct { + name string + input Type + expected bool + err bool + }{ + { + name: "ValidZlib", + input: TypeZlib, + expected: true, + }, + { + name: "InvalidZlib", + input: TypeGzip, + expected: false, + }, + { + name: "ValidZlibCompressionLevel", + input: "zlib/1", + expected: true, + }, + { + name: "InvalidZlibCompressionLevel", + input: "zlib/10", + expected: false, + }, + { + name: "InvalidZlibCompressionLevel", + input: "zlib/one", + expected: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equal(t, tt.expected, tt.input.IsZlib()) + }) + } +} diff --git a/config/confighttp/compression_test.go b/config/confighttp/compression_test.go index 89fd471c04c..680156f0373 100644 --- a/config/confighttp/compression_test.go +++ b/config/confighttp/compression_test.go @@ -87,6 +87,18 @@ func TestHTTPClientCompression(t *testing.T) { reqBody: compressedZstdBody.Bytes(), shouldError: false, }, + { + name: "InvalidZlib", + encoding: "zlib/one", + reqBody: compressedZstdBody.Bytes(), + shouldError: true, + }, + { + name: "InvalidSnappy", + encoding: "snappy/1", + reqBody: compressedZstdBody.Bytes(), + shouldError: true, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -108,13 +120,13 @@ func TestHTTPClientCompression(t *testing.T) { Compression: tt.encoding, } client, err := clientSettings.ToClient(context.Background(), componenttest.NewNopHost(), componenttest.NewNopTelemetrySettings()) - require.NoError(t, err) - res, err := client.Do(req) if tt.shouldError { assert.Error(t, err) return } require.NoError(t, err) + res, err := client.Do(req) + require.NoError(t, err) _, err = io.ReadAll(res.Body) require.NoError(t, err) diff --git a/config/confighttp/confighttp.go b/config/confighttp/confighttp.go index 846728b815e..f963fa0390e 100644 --- a/config/confighttp/confighttp.go +++ b/config/confighttp/confighttp.go @@ -17,6 +17,7 @@ import ( "strings" "time" + "github.com/klauspost/compress/zlib" "github.com/rs/cors" "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" "go.opentelemetry.io/otel" @@ -134,11 +135,11 @@ func NewDefaultClientConfig() ClientConfig { } } -func setCompression(compressionField configcompression.Type) (compressionType configcompression.Type, compressionLevel int) { +// Gets the compression type and level from the configuration. +func getCompression(compressionField configcompression.Type) (compressionType configcompression.Type, compressionLevel int) { parts := strings.Split(string(compressionField), "/") - // Set compression type - compressionLevel = 1 + compressionLevel = zlib.DefaultCompression compressionType = configcompression.Type(parts[0]) if len(parts) > 1 { levelStr := parts[1] @@ -235,7 +236,7 @@ func (hcs *ClientConfig) ToClient(ctx context.Context, host component.Host, sett // Supporting gzip, zlib, deflate, snappy, and zstd; none is treated as uncompressed. if hcs.Compression.IsCompressed() { if hcs.Compression.IsZstd() || hcs.Compression.IsGzip() || hcs.Compression.IsZlib() { - compressionType, compressionLevel := setCompression(hcs.Compression) + compressionType, compressionLevel := getCompression(hcs.Compression) compression := CompressionOptions{compressionType, compressionLevel} clientTransport, err = newCompressRoundTripper(clientTransport, compression) if err != nil {