bitbucket.org/ai69/amoy@v0.2.3/channel_test.go (about) 1 package amoy 2 3 import ( 4 "fmt" 5 "reflect" 6 "testing" 7 8 "github.com/1set/gut/yhash" 9 "github.com/1set/gut/yrand" 10 ) 11 12 func BenchmarkAccumulatedChannel(b *testing.B) { 13 var ( 14 dataSize = 2048 15 bufSize = 500 16 chunkSize = 128 17 ) 18 rawStr, _ := yrand.StringBase62(dataSize) 19 rawBytes := []byte(rawStr) 20 21 b.ResetTimer() 22 for i := 0; i < b.N; i++ { 23 inCh := make(chan []byte) 24 outCh := AccumulatedChannel(inCh, bufSize) 25 done := make(chan struct{}) 26 go func() { 27 for range outCh { 28 //revive:disable:empty-block 29 // yes, it's empty 30 } 31 close(done) 32 }() 33 fillChannelRandomChunk(inCh, rawBytes, chunkSize, chunkSize) 34 close(inCh) 35 <-done 36 } 37 } 38 39 func TestAccumulatedChannel(t *testing.T) { 40 tests := []struct { 41 dataSize int 42 batchSize int 43 minSize int 44 maxSize int 45 }{ 46 {0, 1, 1, 1}, 47 {1, 1, 1, 1}, 48 {1024, 1, 1, 1}, 49 {1024, 10, 2, 2}, 50 {1024, 10, 2, 5}, 51 {1024, 1024, 2, 5}, 52 {1024, 1025, 2, 5}, 53 {1024, 10, 1024, 1024}, 54 {1024, 1024, 1024, 1024}, 55 {1024, 10, 2048, 2048}, 56 } 57 for _, tt := range tests { 58 name := fmt.Sprintf("%d->(%d,%d-%d)", tt.dataSize, tt.batchSize, tt.minSize, tt.maxSize) 59 t.Run(name, func(t *testing.T) { 60 var ( 61 rawBytes []byte 62 cumBytes []byte 63 ) 64 rawStr, _ := yrand.StringBase62(tt.dataSize) 65 if len(rawStr) > 0 { 66 rawBytes = []byte(rawStr) 67 } 68 69 inCh := make(chan []byte) 70 outCh := AccumulatedChannel(inCh, tt.batchSize) 71 done := make(chan struct{}) 72 go func() { 73 for v := range outCh { 74 cumBytes = append(cumBytes, v...) 75 } 76 close(done) 77 }() 78 fillChannelRandomChunk(inCh, rawBytes, tt.minSize, tt.maxSize) 79 close(inCh) 80 <-done 81 82 if !reflect.DeepEqual(rawBytes, cumBytes) { 83 rh, _ := yhash.BytesMD5(rawBytes) 84 ch, _ := yhash.BytesMD5(cumBytes) 85 t.Errorf("AccumulatedChannel([%d]%v) != [%d]%v breaks data", len(rawBytes), rh, len(cumBytes), ch) 86 } 87 }) 88 } 89 } 90 91 func TestBlockForever(t *testing.T) { 92 go func() { 93 BlockForever() 94 t.Errorf("BlockForever() should not return") 95 }() 96 SleepForMilliseconds(10) 97 } 98 99 // fillChannelRandomChunk fills the channel with given data in random chunk sizes (min <= size < max). 100 func fillChannelRandomChunk(in chan []byte, data []byte, min, max int) { 101 var pos int 102 for { 103 l := min 104 if min < max { 105 l, _ = yrand.IntRange(min, max) 106 } 107 if l == 0 { 108 in <- []byte{} 109 continue 110 } 111 if pos+l > len(data) { 112 l = len(data) - pos 113 } 114 in <- data[pos : pos+l] 115 pos += l 116 if pos >= len(data) { 117 break 118 } 119 } 120 }