From e593a04faf9e76341ad8ec85bef8e54e643115aa Mon Sep 17 00:00:00 2001 From: Saxon Date: Wed, 13 Mar 2019 18:14:00 +1030 Subject: [PATCH] revid: added TestResetEncoderSenderSetup Added a test to check that revid's reset method is correctly setting up encoders and the senders they write to correctly. --- revid/revid.go | 6 +- revid/revid_test.go | 194 ++++++++++++++++++++++++++++++++++++++++++++ revid/senders.go | 6 +- 3 files changed, 197 insertions(+), 9 deletions(-) diff --git a/revid/revid.go b/revid/revid.go index 2ec5286b..00679285 100644 --- a/revid/revid.go +++ b/revid/revid.go @@ -180,6 +180,7 @@ func (r *Revid) reset(config Config) error { r.buffer = (*buffer)(ring.NewBuffer(ringBufferSize, ringBufferElementSize, writeTimeout)) + r.encoder = make([]stream.Encoder, 0) // mtsSenders will hold the senders the require MPEGTS encoding, and flvSenders // will hold senders that require FLV encoding. var mtsSenders, flvSenders []loadSender @@ -201,10 +202,7 @@ func (r *Revid) reset(config Config) error { case File: sender, err = newFileSender(r.config.OutputPath) case Rtmp: - sender, err = newRtmpSender(r.config.RtmpUrl, rtmpConnectionTimeout, rtmpConnectionMaxTries, false, r.config.Logger.Log) - if err != nil { - return err - } + sender, _ = newRtmpSender(r.config.RtmpUrl, rtmpConnectionTimeout, rtmpConnectionMaxTries, false, r.config.Logger.Log) flvSenders = append(flvSenders, sender) continue } diff --git a/revid/revid_test.go b/revid/revid_test.go index d88e4e9a..2f995117 100644 --- a/revid/revid_test.go +++ b/revid/revid_test.go @@ -1,11 +1,15 @@ package revid import ( + "errors" "fmt" "os" "runtime" "testing" + "bitbucket.org/ausocean/av/stream" + "bitbucket.org/ausocean/av/stream/flv" + "bitbucket.org/ausocean/av/stream/mts" "bitbucket.org/ausocean/iot/pi/netsender" ) @@ -66,3 +70,193 @@ func (tl *testLogger) Log(level int8, msg string, params ...interface{}) { os.Exit(1) } } + +// TestResetEncoderSenderSetup checks that revid.reset() correctly sets up the +// revid.encoder slice and the senders the encoders write to. +func TestResetEncoderSenderSetup(t *testing.T) { + // We will use these to indicate types after assertion. + const ( + mtsSenderStr = "revid.mtsSender" + rtpSenderStr = "revid.rtpSender" + rtmpSenderStr = "revid.RtmpSender" + mtsEncoderStr = "mts.Encoder" + flvEncoderStr = "flv.Encoder" + ) + + // Struct that will be used to format test cases nicely below. + type encoder struct { + encoderType string + destinations []string + } + + tests := []struct { + outputs []uint8 + encoders []encoder + }{ + { + outputs: []uint8{Http}, + encoders: []encoder{ + { + encoderType: mtsEncoderStr, + destinations: []string{mtsSenderStr}, + }, + }, + }, + { + outputs: []uint8{Rtmp}, + encoders: []encoder{ + { + encoderType: flvEncoderStr, + destinations: []string{rtmpSenderStr}, + }, + }, + }, + { + outputs: []uint8{Rtp}, + encoders: []encoder{ + { + encoderType: mtsEncoderStr, + destinations: []string{rtpSenderStr}, + }, + }, + }, + { + outputs: []uint8{Http, Rtmp}, + encoders: []encoder{ + { + encoderType: mtsEncoderStr, + destinations: []string{mtsSenderStr}, + }, + { + encoderType: flvEncoderStr, + destinations: []string{rtmpSenderStr}, + }, + }, + }, + { + outputs: []uint8{Http, Rtp, Rtmp}, + encoders: []encoder{ + { + encoderType: mtsEncoderStr, + destinations: []string{mtsSenderStr, rtpSenderStr}, + }, + { + encoderType: flvEncoderStr, + destinations: []string{rtmpSenderStr}, + }, + }, + }, + { + outputs: []uint8{Rtp, Rtmp}, + encoders: []encoder{ + { + encoderType: mtsEncoderStr, + destinations: []string{rtpSenderStr}, + }, + { + encoderType: flvEncoderStr, + destinations: []string{rtmpSenderStr}, + }, + }, + }, + } + + // typeOfEncoder will return the type of encoder implementing stream.Encoder. + typeOfEncoder := func(i stream.Encoder) (string, error) { + if _, ok := i.(*mts.Encoder); ok { + return mtsEncoderStr, nil + } + if _, ok := i.(*flv.Encoder); ok { + return flvEncoderStr, nil + } + return "", errors.New("unknown Encoder type") + } + + // typeOfSender will return the type of sender implementing loadSender. + typeOfSender := func(s loadSender) (string, error) { + if _, ok := s.(*mtsSender); ok { + return mtsSenderStr, nil + } + if _, ok := s.(*rtpSender); ok { + return rtpSenderStr, nil + } + if _, ok := s.(*rtmpSender); ok { + return rtmpSenderStr, nil + } + return "", errors.New("unknown loadSender type") + } + + rv, err := New(Config{Logger: &testLogger{}}, nil) + if err != nil { + t.Fatalf("unexpected err: %v", err) + } + + // Go through our test cases. + for testNum, test := range tests { + // Create a new config and reset revid with it. + const dummyUrl = "rtmp://dummy" + newConfig := Config{Logger: &testLogger{}, Outputs: test.outputs, RtmpUrl: dummyUrl} + err := rv.reset(newConfig) + if err != nil { + t.Fatalf("unexpected error: %v for test %v", err, testNum) + } + + // First check that we have the correct number of encoders. + got := len(rv.encoder) + want := len(test.encoders) + if got != want { + t.Errorf("incorrect number of encoders in revid for test: %v. \nGot: %v\nWant: %v\n", testNum, got, want) + } + + // Now check the correctness of encoders and their destinations. + for _, e := range rv.encoder { + // Get e's type. + encoderType, err := typeOfEncoder(e) + if err != nil { + t.Fatalf("could not get encoders type for test %v, failed with err: %v", testNum, err) + } + + // Check that we expect this encoder to be here. + idx := -1 + for i, expect := range test.encoders { + if expect.encoderType == encoderType { + idx = i + } + } + if idx == -1 { + t.Errorf("encoder %v isn't expected in test %v", encoderType, testNum) + } + + // Now check that this encoder has correct number of destinations (senders). + ms := e.GetDst() + senders := ms.(*multiSender).senders + got = len(senders) + want = len(test.encoders[idx].destinations) + if got != want { + t.Errorf("did not get expected number of senders in test %v. \nGot: %v\nWant: %v\n", testNum, got, want) + } + + // Check that destinations are as expected. + for _, expectDst := range test.encoders[idx].destinations { + ok := false + for _, dst := range senders { + // Get type of sender. + senderType, err := typeOfSender(dst) + if err != nil { + t.Fatalf("could not get encoders type for test %v, failed with err: %v", testNum, err) + } + + // If it's one we want, indicate. + if senderType == expectDst { + ok = true + } + } + + // If not okay then we couldn't find expected sender + if !ok { + t.Errorf("could not find expected destination %v, for test %v", expectDst, testNum) + } + } + } + } +} diff --git a/revid/senders.go b/revid/senders.go index 68b97963..c89d29dc 100644 --- a/revid/senders.go +++ b/revid/senders.go @@ -384,10 +384,6 @@ func newRtmpSender(url string, timeout uint, retries int, retry bool, log func(l log(logger.Info, pkg+"retry rtmp connection") } } - if err != nil { - return nil, err - } - s := &rtmpSender{ conn: conn, url: url, @@ -396,7 +392,7 @@ func newRtmpSender(url string, timeout uint, retries int, retry bool, log func(l log: log, retry: retry, } - return s, nil + return s, err } func (s *rtmpSender) load(d []byte) error {