github.com/cnotch/ipchub@v1.1.0/media/stream_test.go (about) 1 // Copyright (c) 2019,CAOHONGJU All rights reserved. 2 // Use of this source code is governed by a MIT-style 3 // license that can be found in the LICENSE file. 4 5 package media 6 7 import ( 8 "io" 9 "testing" 10 "time" 11 12 "github.com/cnotch/ipchub/av/format/rtp" 13 "github.com/stretchr/testify/assert" 14 ) 15 16 type emptyMulticastable struct { 17 } 18 19 func (m emptyMulticastable) AddMember(io.Closer) {} 20 func (m emptyMulticastable) ReleaseMember(io.Closer) {} 21 func (m emptyMulticastable) MulticastIP() string { return "234.0.0.1" } 22 func (m emptyMulticastable) Port(int) int { return 0 } 23 func (m emptyMulticastable) SourceIP() string { return "234.0.0.1" } 24 func (m emptyMulticastable) TTL() int { return 0 } 25 26 type emptyConsumer struct { 27 } 28 29 func (c emptyConsumer) Consume(pack Pack) {} 30 func (c emptyConsumer) Close() error { return nil } 31 32 type panicConsumer struct { 33 try int 34 } 35 36 func (c *panicConsumer) Consume(pack Pack) { 37 c.try++ 38 if c.try > 3 { 39 panic("panicConsumer") 40 } 41 } 42 func (c *panicConsumer) Close() error { return nil } 43 44 const sdpRaw = `v=0 45 o=- 0 0 IN IP4 127.0.0.1 46 s=No Name 47 c=IN IP4 127.0.0.1 48 t=0 0 49 a=tool:libavformat 58.20.100 50 m=video 0 RTP/AVP 96 51 b=AS:2500 52 a=rtpmap:96 H264/90000 53 a=fmtp:96 packetization-mode=1; sprop-parameter-sets=Z2QAH6zZQFAFuhAAAAMAEAAAAwPI8YMZYA==,aO+8sA==; profile-level-id=64001F 54 a=control:streamid=0 55 m=audio 0 RTP/AVP 97 56 b=AS:160 57 a=rtpmap:97 MPEG4-GENERIC/44100/2 58 a=fmtp:97 profile-level-id=1;mode=AAC-hbr;sizelength=13;indexlength=3;indexdeltalength=3; config=121056E500 59 a=control:streamid=1 60 ` 61 62 func TestNewStream(t *testing.T) { 63 tests := []struct { 64 name string 65 path string 66 options []Option 67 }{ 68 { 69 name: "test01", 70 path: "/live/enter", 71 options: []Option{Attr(" ok ", "ok"), Attr("name", "chj"), Multicast(emptyMulticastable{})}, 72 }, 73 } 74 for _, tt := range tests { 75 t.Run(tt.name, func(t *testing.T) { 76 got := NewStream(tt.path, sdpRaw, tt.options...) 77 v := got.Attr("Ok") 78 assert.Equal(t, "ok", v, "Must is ok") 79 assert.NotNil(t, got.Multicastable(), "Must is not nil") 80 }) 81 } 82 } 83 84 func Test_Consumption_Consume(t *testing.T) { 85 s := NewStream("live/test", sdpRaw) 86 87 t.Run("Consumption_Consume", func(t *testing.T) { 88 closed := false 89 go func() { 90 for !closed { 91 s.WriteRtpPacket(&rtp.Packet{}) 92 <-time.After(time.Millisecond * 1) 93 } 94 }() 95 cid := s.StartConsume(emptyConsumer{}, RTPPacket, "") 96 assert.Equal(t, 1, s.consumptions.Count(), "must is 1") 97 98 <-time.After(time.Millisecond * 1000) 99 cinfo, ok := s.GetConsumption(cid) 100 assert.True(t, ok, "must is true") 101 assert.NotZero(t, cinfo.Flow.OutBytes, "must > 0") 102 103 s.StopConsume(cid) 104 assert.Equal(t, 0, s.consumptions.Count(), "must is 0") 105 closed = true 106 s.Close() 107 }) 108 } 109 110 func Test_Consumption_ConsumePanic(t *testing.T) { 111 s := NewStream("live/test", sdpRaw) 112 t.Run("Test_Consumption_ConsumePanic", func(t *testing.T) { 113 closed := false 114 go func() { 115 for !closed { 116 s.WriteRtpPacket(&rtp.Packet{}) 117 <-time.After(time.Millisecond * 1) 118 } 119 }() 120 s.StartConsume(&panicConsumer{}, RTPPacket, "") 121 assert.Equal(t, 1, s.consumptions.Count(), "must is 1") 122 123 <-time.After(time.Millisecond * 100) 124 assert.Equal(t, 0, s.consumptions.Count(), "panic autoclose,must is 0") 125 closed = true 126 s.Close() 127 }) 128 } 129 130 func benchDispatch(n int, b *testing.B) { 131 s := NewStream("/live/a", sdpRaw) 132 for i := 0; i < n; i++ { 133 s.StartConsume(emptyConsumer{}, RTPPacket, "") 134 } 135 136 b.ResetTimer() 137 b.RunParallel(func(pb *testing.PB) { 138 for pb.Next() { 139 s.WriteRtpPacket(&rtp.Packet{}) 140 } 141 }) 142 s.Close() 143 } 144 func Benchmark_Stream_Dispatch1(b *testing.B) { 145 benchDispatch(1, b) 146 } 147 func Benchmark_Stream_Dispatch5(b *testing.B) { 148 benchDispatch(5, b) 149 } 150 func Benchmark_Stream_Dispatch10(b *testing.B) { 151 benchDispatch(10, b) 152 } 153 func Benchmark_Stream_Dispatch50(b *testing.B) { 154 benchDispatch(50, b) 155 } 156 func Benchmark_Stream_Dispatch100(b *testing.B) { 157 benchDispatch(100, b) 158 } 159 func Benchmark_Stream_Dispatch500(b *testing.B) { 160 benchDispatch(500, b) 161 } 162 163 func Benchmark_Stream_Dispatch1000(b *testing.B) { 164 benchDispatch(1000, b) 165 } 166 167 func Benchmark_Stream_Dispatch10000(b *testing.B) { 168 benchDispatch(10000, b) 169 }