github.com/sandwich-go/boost@v1.3.29/xencoding/protobuf/codec_test.go (about) 1 package protobuf 2 3 import ( 4 "bytes" 5 "context" 6 "github.com/sandwich-go/boost/xencoding" 7 "sync" 8 "testing" 9 10 "github.com/sandwich-go/boost/xencoding/protobuf/test_perf" 11 ) 12 13 func marshalAndUnmarshal(t *testing.T, codec xencoding.Codec, expectedBody []byte) { 14 p := &test_perf.Buffer{} 15 p.Body = expectedBody 16 17 marshalledBytes, err := codec.Marshal(context.Background(), p) 18 if err != nil { 19 t.Errorf("codec.Marshal(_) returned an error") 20 } 21 22 if err := codec.Unmarshal(context.Background(), marshalledBytes, p); err != nil { 23 t.Errorf("codec.Unmarshal(_) returned an error") 24 } 25 26 if !bytes.Equal(p.GetBody(), expectedBody) { 27 t.Errorf("Unexpected body; got %v; want %v", p.GetBody(), expectedBody) 28 } 29 } 30 31 func TestBasicProtoCodecMarshalAndUnmarshal(t *testing.T) { 32 marshalAndUnmarshal(t, &codec{}, []byte{1, 2, 3}) 33 } 34 func TestBasicJsonCodecMarshalAndUnmarshal(t *testing.T) { 35 marshalAndUnmarshal(t, &codec{}, []byte{1, 2, 3}) 36 } 37 38 // Try to catch possible race conditions around use of pools 39 func TestConcurrentUsage(t *testing.T) { 40 const ( 41 numGoRoutines = 100 42 numMarshUnmarsh = 1000 43 ) 44 45 // small, arbitrary byte slices 46 protoBodies := [][]byte{ 47 []byte("one"), 48 []byte("two"), 49 []byte("three"), 50 []byte("four"), 51 []byte("five"), 52 } 53 54 var wg sync.WaitGroup 55 codec := &codec{} 56 57 for i := 0; i < numGoRoutines; i++ { 58 wg.Add(1) 59 go func() { 60 defer wg.Done() 61 for k := 0; k < numMarshUnmarsh; k++ { 62 marshalAndUnmarshal(t, codec, protoBodies[k%len(protoBodies)]) 63 } 64 }() 65 } 66 67 wg.Wait() 68 } 69 70 // TestStaggeredMarshalAndUnmarshalUsingSamePool tries to catch potential errors in which slices get 71 // stomped on during reuse of a proto.Buffer. 72 func TestStaggeredMarshalAndUnmarshalUsingSamePool(t *testing.T) { 73 codec1 := codec{} 74 codec2 := codec{} 75 76 expectedBody1 := []byte{1, 2, 3} 77 expectedBody2 := []byte{4, 5, 6} 78 79 proto1 := test_perf.Buffer{Body: expectedBody1} 80 proto2 := test_perf.Buffer{Body: expectedBody2} 81 82 var m1, m2 []byte 83 var err error 84 85 if m1, err = codec1.Marshal(context.Background(), &proto1); err != nil { 86 t.Errorf("codec.Marshal(%v) failed", proto1) 87 } 88 89 if m2, err = codec2.Marshal(context.Background(), &proto2); err != nil { 90 t.Errorf("codec.Marshal(%v) failed", proto2) 91 } 92 93 if err = codec1.Unmarshal(context.Background(), m1, &proto1); err != nil { 94 t.Errorf("codec.Unmarshal(%v) failed", m1) 95 } 96 97 if err = codec2.Unmarshal(context.Background(), m2, &proto2); err != nil { 98 t.Errorf("codec.Unmarshal(%v) failed", m2) 99 } 100 101 b1 := proto1.GetBody() 102 b2 := proto2.GetBody() 103 104 for i, v := range b1 { 105 if expectedBody1[i] != v { 106 t.Errorf("expected %v at index %v but got %v", i, expectedBody1[i], v) 107 } 108 } 109 110 for i, v := range b2 { 111 if expectedBody2[i] != v { 112 t.Errorf("expected %v at index %v but got %v", i, expectedBody2[i], v) 113 } 114 } 115 }