github.com/v2fly/v2ray-core/v5@v5.16.2-0.20240507031116-8191faa6e095/transport/pipe/pipe_test.go (about)

     1  package pipe_test
     2  
     3  import (
     4  	"errors"
     5  	"io"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/google/go-cmp/cmp"
    10  	"golang.org/x/sync/errgroup"
    11  
    12  	"github.com/v2fly/v2ray-core/v5/common"
    13  	"github.com/v2fly/v2ray-core/v5/common/buf"
    14  	. "github.com/v2fly/v2ray-core/v5/transport/pipe"
    15  )
    16  
    17  func TestPipeReadWrite(t *testing.T) {
    18  	pReader, pWriter := New(WithSizeLimit(1024))
    19  
    20  	b := buf.New()
    21  	b.WriteString("abcd")
    22  	common.Must(pWriter.WriteMultiBuffer(buf.MultiBuffer{b}))
    23  
    24  	b2 := buf.New()
    25  	b2.WriteString("efg")
    26  	common.Must(pWriter.WriteMultiBuffer(buf.MultiBuffer{b2}))
    27  
    28  	rb, err := pReader.ReadMultiBuffer()
    29  	common.Must(err)
    30  	if r := cmp.Diff(rb.String(), "abcdefg"); r != "" {
    31  		t.Error(r)
    32  	}
    33  }
    34  
    35  func TestPipeInterrupt(t *testing.T) {
    36  	pReader, pWriter := New(WithSizeLimit(1024))
    37  	payload := []byte{'a', 'b', 'c', 'd'}
    38  	b := buf.New()
    39  	b.Write(payload)
    40  	common.Must(pWriter.WriteMultiBuffer(buf.MultiBuffer{b}))
    41  	pWriter.Interrupt()
    42  
    43  	rb, err := pReader.ReadMultiBuffer()
    44  	if err != io.ErrClosedPipe {
    45  		t.Fatal("expect io.ErrClosePipe, but got ", err)
    46  	}
    47  	if !rb.IsEmpty() {
    48  		t.Fatal("expect empty buffer, but got ", rb.Len())
    49  	}
    50  }
    51  
    52  func TestPipeClose(t *testing.T) {
    53  	pReader, pWriter := New(WithSizeLimit(1024))
    54  	payload := []byte{'a', 'b', 'c', 'd'}
    55  	b := buf.New()
    56  	common.Must2(b.Write(payload))
    57  	common.Must(pWriter.WriteMultiBuffer(buf.MultiBuffer{b}))
    58  	common.Must(pWriter.Close())
    59  
    60  	rb, err := pReader.ReadMultiBuffer()
    61  	common.Must(err)
    62  	if rb.String() != string(payload) {
    63  		t.Fatal("expect content ", string(payload), " but actually ", rb.String())
    64  	}
    65  
    66  	rb, err = pReader.ReadMultiBuffer()
    67  	if err != io.EOF {
    68  		t.Fatal("expected EOF, but got ", err)
    69  	}
    70  	if !rb.IsEmpty() {
    71  		t.Fatal("expect empty buffer, but got ", rb.String())
    72  	}
    73  }
    74  
    75  func TestPipeLimitZero(t *testing.T) {
    76  	pReader, pWriter := New(WithSizeLimit(0))
    77  	bb := buf.New()
    78  	common.Must2(bb.Write([]byte{'a', 'b'}))
    79  	common.Must(pWriter.WriteMultiBuffer(buf.MultiBuffer{bb}))
    80  
    81  	var errg errgroup.Group
    82  	errg.Go(func() error {
    83  		b := buf.New()
    84  		b.Write([]byte{'c', 'd'})
    85  		return pWriter.WriteMultiBuffer(buf.MultiBuffer{b})
    86  	})
    87  	errg.Go(func() error {
    88  		time.Sleep(time.Second)
    89  
    90  		var container buf.MultiBufferContainer
    91  		if err := buf.Copy(pReader, &container); err != nil {
    92  			return err
    93  		}
    94  
    95  		if r := cmp.Diff(container.String(), "abcd"); r != "" {
    96  			return errors.New(r)
    97  		}
    98  		return nil
    99  	})
   100  	errg.Go(func() error {
   101  		time.Sleep(time.Second * 2)
   102  		return pWriter.Close()
   103  	})
   104  	if err := errg.Wait(); err != nil {
   105  		t.Error(err)
   106  	}
   107  }
   108  
   109  func TestPipeWriteMultiThread(t *testing.T) {
   110  	pReader, pWriter := New(WithSizeLimit(0))
   111  
   112  	var errg errgroup.Group
   113  	for i := 0; i < 10; i++ {
   114  		errg.Go(func() error {
   115  			b := buf.New()
   116  			b.WriteString("abcd")
   117  			return pWriter.WriteMultiBuffer(buf.MultiBuffer{b})
   118  		})
   119  	}
   120  	time.Sleep(time.Millisecond * 100)
   121  	pWriter.Close()
   122  	errg.Wait()
   123  
   124  	b, err := pReader.ReadMultiBuffer()
   125  	common.Must(err)
   126  	if r := cmp.Diff(b[0].Bytes(), []byte{'a', 'b', 'c', 'd'}); r != "" {
   127  		t.Error(r)
   128  	}
   129  }
   130  
   131  func TestInterfaces(t *testing.T) {
   132  	_ = (buf.Reader)(new(Reader))
   133  	_ = (buf.TimeoutReader)(new(Reader))
   134  
   135  	_ = (common.Interruptible)(new(Reader))
   136  	_ = (common.Interruptible)(new(Writer))
   137  	_ = (common.Closable)(new(Writer))
   138  }
   139  
   140  func BenchmarkPipeReadWrite(b *testing.B) {
   141  	reader, writer := New(WithoutSizeLimit())
   142  	a := buf.New()
   143  	a.Extend(buf.Size)
   144  	c := buf.MultiBuffer{a}
   145  
   146  	b.ResetTimer()
   147  	for i := 0; i < b.N; i++ {
   148  		common.Must(writer.WriteMultiBuffer(c))
   149  		d, err := reader.ReadMultiBuffer()
   150  		common.Must(err)
   151  		c = d
   152  	}
   153  }