Repository: grpc/grpc-go
File: rpc_util_test.go (Go)

Code before:
		wantErr               error
	}{
		{
			name:                  "Decompresses successfully with sufficient buffer size",
			input:                 mustCompress(t, []byte("decompressed data")),
			maxReceiveMessageSize: 50,
			want:                  []byte("decompressed data"),
			wantErr:               nil,
		},
		{
			name:                  "Fails due to exceeding maxReceiveMessageSize",
			input:                 mustCompress(t, []byte("message that is too large")),
			maxReceiveMessageSize: len("message that is too large") - 1,
			want:                  nil,
			wantErr:               errMaxMessageSizeExceeded,
		},
		{
			name:                  "Decompresses to exactly maxReceiveMessageSize",
			input:                 mustCompress(t, []byte("exact size message")),
			maxReceiveMessageSize: len("exact size message"),
			want:                  []byte("exact size message"),
			wantErr:               nil,
		},
		{
			name:                  "Handles large buffer size MaxInt",
			input:                 mustCompress(t, []byte("large message")),
			maxReceiveMessageSize: math.MaxInt,
			want:                  []byte("large message"),
			wantErr:               nil,
		},
	}

	for _, tc := range testCases {
		t.Run(tc.name, func(t *testing.T) {
			output, err := decompress(compressor, tc.input, tc.maxReceiveMessageSize, mem.DefaultBufferPool())
			if !cmp.Equal(err, tc.wantErr, cmpopts.EquateErrors()) {
				t.Fatalf("decompress() err = %v, wantErr = %v", err, tc.wantErr)
			}
			if !cmp.Equal(tc.want, output.Materialize()) {
				t.Fatalf("decompress() output mismatch: got = %v, want = %v", output.Materialize(), tc.want)
			}
		})
	}
}


Review comment (bug):
large message is confusing. The bug which we are solving returns nil irrespective of what message size is if maxReceiveMessageSize is math.MaxInt. The test can be just `Decompresses successfully with maxReceiveMessageSize MaxInt`. Basically it can be similar to first test case except the maxReceiveMessageSize is MaxInt. 

The other test case where you are actually going to overflow by providing a message larger than MaxInt is hard to write as unit test

Code after:
// Do simulates decompression. It returns a predefined error if ShouldError is true,
// or a fixed set of decompressed data if ShouldError is false.
func (m *MockDecompressor) Do(_ io.Reader) ([]byte, error) {
	if m.ShouldError {
		return nil, errors.New(decompressionErrorMsg)
	}
	return []byte(defaultDecompressedData), nil
}

// Type returns the string identifier for the MockDecompressor.
func (m *MockDecompressor) Type() string {
	return "MockDecompressor"
}

// TestDecompress tests the decompress function behaves correctly for following scenarios
// decompress successfully when message is <= maxReceiveMessageSize
// errors when message > maxReceiveMessageSize
// decompress successfully when maxReceiveMessageSize is MaxInt
// errors when the decompressed message has an invalid format
// errors when the decompressed message exceeds the maxReceiveMessageSize.
func (s) TestDecompress(t *testing.T) {
	compressor := encoding.GetCompressor("gzip")
	validDecompressor := &MockDecompressor{ShouldError: false}
	invalidFormatDecompressor := &MockDecompressor{ShouldError: true}

	testCases := []struct {
		name                  string
		input                 mem.BufferSlice
		dc                    Decompressor
		maxReceiveMessageSize int
		want                  []byte
		wantErr               error
	}{
		{
			name:                  "Decompresses successfully with sufficient buffer size",
			input:                 compressWithDeterministicError(t, []byte("decompressed data")),
			dc:                    nil,
			maxReceiveMessageSize: 50,
			want:                  []byte("decompressed data"),
			wantErr:               nil,
		},
		{
			name:                  "Fails due to exceeding maxReceiveMessageSize",
			input:                 compressWithDeterministicError(t, []byte("message that is too large")),
			dc:                    nil,
			maxReceiveMessageSize: len("message that is too large") - 1,
			want:                  nil,
			wantErr:               status.Errorf(codes.ResourceExhausted, "grpc: received message after decompression larger than max %d", len("message that is too large")-1),
		},
		{
			name:                  "Decompresses to exactly maxReceiveMessageSize",