github.com/koko1123/flow-go-1@v0.29.6/network/p2p/compressed/compressedStream_test.go (about)

     1  package compressed
     2  
     3  import (
     4  	"io"
     5  	"sync"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/stretchr/testify/require"
    10  
    11  	"github.com/koko1123/flow-go-1/network/compressor"
    12  	"github.com/koko1123/flow-go-1/utils/unittest"
    13  )
    14  
    15  // TestHappyPath evaluates reading from a compressed stream retrieves what originally has been written on it.
    16  func TestHappyPath(t *testing.T) {
    17  	text := "hello world, hello world!"
    18  	textByte := []byte(text)
    19  	textByteLen := len(textByte)
    20  
    21  	// creates a pair of compressed streams
    22  	mca, _, mcb, _ := newCompressedStreamPair(t)
    23  
    24  	// writes on stream mca
    25  	writeWG := sync.WaitGroup{}
    26  	writeWG.Add(1)
    27  	go func() {
    28  		defer writeWG.Done()
    29  
    30  		n, err := mca.Write(textByte)
    31  		require.NoError(t, err)
    32  
    33  		require.Equal(t, n, len(text))
    34  	}()
    35  
    36  	// write on stream mca should be read on steam mcb
    37  	readWG := sync.WaitGroup{}
    38  	readWG.Add(1)
    39  	go func() {
    40  		defer readWG.Done()
    41  
    42  		b := make([]byte, textByteLen)
    43  		n, err := mcb.Read(b)
    44  		require.NoError(t, err)
    45  
    46  		require.Equal(t, n, textByteLen)
    47  		require.Equal(t, b, textByte)
    48  	}()
    49  
    50  	unittest.RequireReturnsBefore(t, writeWG.Wait, 1*time.Second, "timeout for writing on stream")
    51  	unittest.RequireReturnsBefore(t, readWG.Wait, 1*time.Second, "timeout for reading from stream")
    52  }
    53  
    54  // TestUnhappyPath evaluates that sending uncompressed data to the compressed end of a stream results
    55  // in an error at the reader side.
    56  func TestUnhappyPath(t *testing.T) {
    57  	text := "hello world, hello world!"
    58  	textByte := []byte(text)
    59  	textByteLen := len(textByte)
    60  
    61  	// sa is the underlying stream of sender (non-compressed)
    62  	// mcb is the compressed stream of receiver
    63  	_, sa, mcb, _ := newCompressedStreamPair(t)
    64  
    65  	// writes on sa (uncompressed)
    66  	writeWG := sync.WaitGroup{}
    67  	writeWG.Add(1)
    68  	go func() {
    69  		defer writeWG.Done()
    70  
    71  		// writes data uncompressed
    72  		n, err := sa.Write(textByte)
    73  		require.NoError(t, err)
    74  
    75  		require.Equal(t, n, len(text))
    76  	}()
    77  
    78  	// write on uncompressed stream sa should NOT be read on compressed steam mcb
    79  	readWG := sync.WaitGroup{}
    80  	readWG.Add(1)
    81  	go func() {
    82  		defer readWG.Done()
    83  
    84  		b := make([]byte, textByteLen)
    85  		n, err := mcb.Read(b)
    86  		// since a compressed stream is reading an uncompressed data,
    87  		// it should return an error.
    88  		require.Error(t, err)
    89  		// number of bytes read should be zero, and nothing should be written to
    90  		// b on reader side.
    91  		require.Equal(t, n, 0)
    92  		require.Equal(t, b, make([]byte, textByteLen))
    93  	}()
    94  
    95  	unittest.RequireReturnsBefore(t, writeWG.Wait, 1*time.Second, "timeout for writing on stream")
    96  	unittest.RequireReturnsBefore(t, readWG.Wait, 1*time.Second, "timeout for reading from stream")
    97  }
    98  
    99  // newStreamPair is a test helper that creates a pair of compressed streams a and b such that
   100  // a reads what b writes and b reads what a writes.
   101  func newStreamPair() (*mockStream, *mockStream) {
   102  	ra, wb := io.Pipe()
   103  	rb, wa := io.Pipe()
   104  
   105  	sa := newMockStream(wa, ra)
   106  	sb := newMockStream(wb, rb)
   107  
   108  	return sa, sb
   109  }
   110  
   111  // newCompressedStreamPair is a test helper that creates a pair of compressed streams a and b such that
   112  // a reads what b writes and b reads what a writes.
   113  func newCompressedStreamPair(t *testing.T) (*compressedStream, *mockStream, *compressedStream, *mockStream) {
   114  	sa, sb := newStreamPair()
   115  
   116  	mca, err := NewCompressedStream(sa, compressor.GzipStreamCompressor{})
   117  	require.NoError(t, err)
   118  
   119  	mcb, err := NewCompressedStream(sb, compressor.GzipStreamCompressor{})
   120  	require.NoError(t, err)
   121  
   122  	return mca, sa, mcb, sb
   123  }