1// +build !js
2
3package webrtc
4
5import (
6	"errors"
7	"math/rand"
8	"strings"
9	"testing"
10	"time"
11
12	"github.com/pion/webrtc/v2/pkg/media"
13)
14
15func check(err error) {
16	if err != nil {
17		panic(err)
18	}
19}
20
21func runOfferingPeer(offerChan chan<- SessionDescription, answerChan <-chan SessionDescription) {
22	config := Configuration{}
23	peerConnection, err := NewPeerConnection(config)
24	check(err)
25
26	track, err := peerConnection.NewTrack(DefaultPayloadTypeOpus, rand.Uint32(), "audio", "pion1")
27	check(err)
28	_, err = peerConnection.AddTrack(track)
29	check(err)
30
31	offer, err := peerConnection.CreateOffer(nil)
32	check(err)
33	err = peerConnection.SetLocalDescription(offer)
34	check(err)
35	offerChan <- offer
36
37	answer := <-answerChan
38	err = peerConnection.SetRemoteDescription(answer)
39	check(err)
40
41	for {
42		// send bogus data
43		sample := media.Sample{
44			Data:    []byte{0x00},
45			Samples: 1,
46		}
47		err = track.WriteSample(sample)
48		check(err)
49	}
50}
51
52func runAnsweringPeer(offerChan <-chan SessionDescription, answerChan chan<- SessionDescription, resultChan chan<- error) {
53	s := SettingEngine{
54		LoggerFactory: testCatchAllLoggerFactory{
55			callback: func(msg string) {
56				if strings.Contains(msg, "SetLocalDescription not called") {
57					resultChan <- nil
58				}
59			},
60		},
61	}
62	api := NewAPI(WithSettingEngine(s))
63	api.mediaEngine.RegisterDefaultCodecs()
64
65	peerConnection, err := api.NewPeerConnection(Configuration{})
66	check(err)
67
68	_, err = peerConnection.AddTransceiver(RTPCodecTypeAudio)
69	check(err)
70
71	peerConnection.OnTrack(func(track *Track, receiver *RTPReceiver) {
72		buf := make([]byte, 1400)
73		_, err = track.Read(buf)
74		check(err)
75		resultChan <- errors.New("Data erroneously received")
76	})
77
78	offer := <-offerChan
79	err = peerConnection.SetRemoteDescription(offer)
80	check(err)
81
82	answer, err := peerConnection.CreateAnswer(nil)
83	check(err)
84	answerChan <- answer
85}
86
87func TestNoPanicIfSetLocalDescriptionNotCalledByAnsweringPeer(t *testing.T) {
88	offerChan := make(chan SessionDescription)
89	answerChan := make(chan SessionDescription)
90	resultChan := make(chan error)
91
92	go runOfferingPeer(offerChan, answerChan)
93	go runAnsweringPeer(offerChan, answerChan, resultChan)
94
95	// wait for either:
96	// - the expected logging (success!)
97	// - the read to succeed (which is actually a bad thing)
98	// - or a timeout (also bad)
99	select {
100	case err := <-resultChan:
101		if err != nil {
102			t.Fatal(err.Error())
103		}
104	case <-time.After(140 * time.Second):
105		t.Fatalf("Timed out waiting for expected logging")
106	}
107}
108