|
|
@@ -0,0 +1,94 @@
|
|
|
+package net
|
|
|
+
|
|
|
+import (
|
|
|
+ "bytes"
|
|
|
+ "crypto/rand"
|
|
|
+ "io"
|
|
|
+ "io/ioutil"
|
|
|
+ "testing"
|
|
|
+
|
|
|
+ "github.com/v2ray/v2ray-core/testing/unit"
|
|
|
+)
|
|
|
+
|
|
|
+func TestReaderAndWrite(t *testing.T) {
|
|
|
+ assert := unit.Assert(t)
|
|
|
+
|
|
|
+ size := 1024 * 1024
|
|
|
+ buffer := make([]byte, size)
|
|
|
+ nBytes, err := rand.Read(buffer)
|
|
|
+ assert.Int(nBytes).Equals(len(buffer))
|
|
|
+ assert.Error(err).IsNil()
|
|
|
+
|
|
|
+ readerBuffer := bytes.NewReader(buffer)
|
|
|
+ writerBuffer := bytes.NewBuffer(make([]byte, 0, size))
|
|
|
+
|
|
|
+ transportChan := make(chan []byte, size/bufferSize*10)
|
|
|
+
|
|
|
+ err = ReaderToChan(transportChan, readerBuffer)
|
|
|
+ assert.Error(err).Equals(io.EOF)
|
|
|
+ close(transportChan)
|
|
|
+
|
|
|
+ err = ChanToWriter(writerBuffer, transportChan)
|
|
|
+ assert.Error(err).IsNil()
|
|
|
+
|
|
|
+ assert.Bytes(buffer).Equals(writerBuffer.Bytes())
|
|
|
+}
|
|
|
+
|
|
|
+type StaticReader struct {
|
|
|
+ total int
|
|
|
+ current int
|
|
|
+}
|
|
|
+
|
|
|
+func (reader *StaticReader) Read(b []byte) (size int, err error) {
|
|
|
+ size = len(b)
|
|
|
+ if size > reader.total-reader.current {
|
|
|
+ size = reader.total - reader.current
|
|
|
+ }
|
|
|
+ //rand.Read(b[:size])
|
|
|
+ reader.current += size
|
|
|
+ if reader.current == reader.total {
|
|
|
+ err = io.EOF
|
|
|
+ }
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+func BenchmarkTransport(b *testing.B) {
|
|
|
+ size := 1024 * 1024
|
|
|
+
|
|
|
+ for i := 0; i < b.N; i++ {
|
|
|
+ transportChanA := make(chan []byte, 128)
|
|
|
+ transportChanB := make(chan []byte, 128)
|
|
|
+
|
|
|
+ readerA := &StaticReader{size, 0}
|
|
|
+ readerB := &StaticReader{size, 0}
|
|
|
+
|
|
|
+ writerA := ioutil.Discard
|
|
|
+ writerB := ioutil.Discard
|
|
|
+
|
|
|
+ finishA := make(chan bool)
|
|
|
+ finishB := make(chan bool)
|
|
|
+
|
|
|
+ go func() {
|
|
|
+ ChanToWriter(writerA, transportChanA)
|
|
|
+ close(finishA)
|
|
|
+ }()
|
|
|
+
|
|
|
+ go func() {
|
|
|
+ ReaderToChan(transportChanA, readerA)
|
|
|
+ close(transportChanA)
|
|
|
+ }()
|
|
|
+
|
|
|
+ go func() {
|
|
|
+ ChanToWriter(writerB, transportChanB)
|
|
|
+ close(finishB)
|
|
|
+ }()
|
|
|
+
|
|
|
+ go func() {
|
|
|
+ ReaderToChan(transportChanB, readerB)
|
|
|
+ close(transportChanB)
|
|
|
+ }()
|
|
|
+
|
|
|
+ <-transportChanA
|
|
|
+ <-transportChanB
|
|
|
+ }
|
|
|
+}
|