github.com/Finschia/finschia-sdk@v0.48.1/codec/types/any_test.go (about)

     1  package types_test
     2  
     3  import (
     4  	"fmt"
     5  	"runtime"
     6  	"runtime/debug"
     7  	"testing"
     8  
     9  	"github.com/gogo/protobuf/proto"
    10  
    11  	"github.com/Finschia/finschia-sdk/codec/types"
    12  	"github.com/Finschia/finschia-sdk/testutil/testdata"
    13  )
    14  
    15  type errOnMarshal struct {
    16  	testdata.Dog
    17  }
    18  
    19  var _ proto.Message = (*errOnMarshal)(nil)
    20  
    21  var errAlways = fmt.Errorf("always erroring")
    22  
    23  func (eom *errOnMarshal) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
    24  	return nil, errAlways
    25  }
    26  
    27  var eom = &errOnMarshal{}
    28  
    29  // Ensure that returning an error doesn't suddenly allocate and waste bytes.
    30  // See https://github.com/cosmos/cosmos-sdk/issues/8537
    31  func TestNewAnyWithCustomTypeURLWithErrorNoAllocation(t *testing.T) {
    32  	var ms1, ms2 runtime.MemStats
    33  
    34  	debug.SetGCPercent(-1) // disable gc. See the comments below for reasons.
    35  	runtime.ReadMemStats(&ms1)
    36  	any, err := types.NewAnyWithValue(eom)
    37  	runtime.ReadMemStats(&ms2)
    38  	debug.SetGCPercent(100) // resume gc
    39  	// Ensure that no fresh allocation was made.
    40  	if diff := ms2.HeapAlloc - ms1.HeapAlloc; diff > 0 {
    41  		// In some cases, `ms1.HeapAlloc` is larger than `ms2.HeapAlloc`.
    42  		// It is probably because the gc worked.
    43  		// That's why we turned off the gc for a while.
    44  		t.Errorf("Unexpected allocation of %d bytes", diff)
    45  	}
    46  	if err == nil {
    47  		t.Fatal("err wasn't returned")
    48  	}
    49  	if any != nil {
    50  		t.Fatalf("Unexpectedly got a non-nil Any value: %v", any)
    51  	}
    52  }
    53  
    54  var sink interface{}
    55  
    56  func BenchmarkNewAnyWithCustomTypeURLWithErrorReturned(b *testing.B) {
    57  	b.ResetTimer()
    58  	b.ReportAllocs()
    59  	for i := 0; i < b.N; i++ {
    60  		any, err := types.NewAnyWithValue(eom)
    61  		if err == nil {
    62  			b.Fatal("err wasn't returned")
    63  		}
    64  		if any != nil {
    65  			b.Fatalf("Unexpectedly got a non-nil Any value: %v", any)
    66  		}
    67  		sink = any
    68  	}
    69  	if sink == nil {
    70  		b.Fatal("benchmark didn't run")
    71  	}
    72  	sink = (interface{})(nil)
    73  }