blob: dc75ba17b3215d2ffbf57b74321fbdb68c96ba41 [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001/*
kjellanderb24317b2016-02-10 07:54:43 -08002 * Copyright 2012 The WebRTC project authors. All Rights Reserved.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003 *
kjellanderb24317b2016-02-10 07:54:43 -08004 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00009 */
10
kwibergd1fe2812016-04-27 06:47:29 -070011#include <memory>
deadbeef3edec7c2016-12-10 11:44:26 -080012#include <sstream>
henrike@webrtc.org28e20752013-07-10 00:45:36 +000013#include <string>
kwiberg0eb15ed2015-12-17 03:04:15 -080014#include <utility>
henrike@webrtc.org28e20752013-07-10 00:45:36 +000015
Henrik Kjellander15583c12016-02-10 10:53:12 +010016#include "webrtc/api/jsepsessiondescription.h"
Henrik Kjellander15583c12016-02-10 10:53:12 +010017#include "webrtc/api/mediastreaminterface.h"
Henrik Kjellander15583c12016-02-10 10:53:12 +010018#include "webrtc/api/peerconnectioninterface.h"
19#include "webrtc/api/rtpreceiverinterface.h"
20#include "webrtc/api/rtpsenderinterface.h"
Henrik Kjellander15583c12016-02-10 10:53:12 +010021#include "webrtc/api/test/fakeconstraints.h"
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000022#include "webrtc/base/gunit.h"
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000023#include "webrtc/base/ssladapter.h"
24#include "webrtc/base/sslstreamadapter.h"
25#include "webrtc/base/stringutils.h"
26#include "webrtc/base/thread.h"
kjellandera96e2d72016-02-04 23:52:28 -080027#include "webrtc/media/base/fakevideocapturer.h"
deadbeef953c2ce2017-01-09 14:53:41 -080028#include "webrtc/media/sctp/sctptransportinternal.h"
Taylor Brandstettera1c30352016-05-13 08:15:11 -070029#include "webrtc/p2p/base/fakeportallocator.h"
ossu7bb87ee2017-01-23 04:56:25 -080030#include "webrtc/pc/audiotrack.h"
kjellander@webrtc.org9b8df252016-02-12 06:47:59 +010031#include "webrtc/pc/mediasession.h"
ossu7bb87ee2017-01-23 04:56:25 -080032#include "webrtc/pc/mediastream.h"
33#include "webrtc/pc/peerconnection.h"
34#include "webrtc/pc/streamcollection.h"
35#include "webrtc/pc/test/fakertccertificategenerator.h"
36#include "webrtc/pc/test/fakevideotracksource.h"
37#include "webrtc/pc/test/mockpeerconnectionobservers.h"
38#include "webrtc/pc/test/testsdpstrings.h"
39#include "webrtc/pc/videocapturertracksource.h"
40#include "webrtc/pc/videotrack.h"
kwibergac9f8762016-09-30 22:29:43 -070041#include "webrtc/test/gmock.h"
42
43#ifdef WEBRTC_ANDROID
ossu7bb87ee2017-01-23 04:56:25 -080044#include "webrtc/pc/test/androidtestinitializer.h"
kwibergac9f8762016-09-30 22:29:43 -070045#endif
henrike@webrtc.org28e20752013-07-10 00:45:36 +000046
47static const char kStreamLabel1[] = "local_stream_1";
48static const char kStreamLabel2[] = "local_stream_2";
49static const char kStreamLabel3[] = "local_stream_3";
50static const int kDefaultStunPort = 3478;
51static const char kStunAddressOnly[] = "stun:address";
52static const char kStunInvalidPort[] = "stun:address:-1";
53static const char kStunAddressPortAndMore1[] = "stun:address:port:more";
54static const char kStunAddressPortAndMore2[] = "stun:address:port more";
55static const char kTurnIceServerUri[] = "turn:user@turn.example.org";
56static const char kTurnUsername[] = "user";
57static const char kTurnPassword[] = "password";
58static const char kTurnHostname[] = "turn.example.org";
Peter Boström0c4e06b2015-10-07 12:23:21 +020059static const uint32_t kTimeout = 10000U;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000060
deadbeefab9b2d12015-10-14 11:33:11 -070061static const char kStreams[][8] = {"stream1", "stream2"};
62static const char kAudioTracks[][32] = {"audiotrack0", "audiotrack1"};
63static const char kVideoTracks[][32] = {"videotrack0", "videotrack1"};
64
deadbeef5e97fb52015-10-15 12:49:08 -070065static const char kRecvonly[] = "recvonly";
66static const char kSendrecv[] = "sendrecv";
67
deadbeefab9b2d12015-10-14 11:33:11 -070068// Reference SDP with a MediaStream with label "stream1" and audio track with
69// id "audio_1" and a video track with id "video_1;
70static const char kSdpStringWithStream1[] =
71 "v=0\r\n"
72 "o=- 0 0 IN IP4 127.0.0.1\r\n"
73 "s=-\r\n"
74 "t=0 0\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -080075 "m=audio 1 RTP/AVPF 103\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -070076 "a=ice-ufrag:e5785931\r\n"
77 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
78 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
79 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -070080 "a=mid:audio\r\n"
deadbeef5e97fb52015-10-15 12:49:08 -070081 "a=sendrecv\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -080082 "a=rtcp-mux\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -070083 "a=rtpmap:103 ISAC/16000\r\n"
84 "a=ssrc:1 cname:stream1\r\n"
85 "a=ssrc:1 mslabel:stream1\r\n"
86 "a=ssrc:1 label:audiotrack0\r\n"
87 "m=video 1 RTP/AVPF 120\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -080088 "a=ice-ufrag:e5785931\r\n"
89 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
90 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
91 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -070092 "a=mid:video\r\n"
deadbeef5e97fb52015-10-15 12:49:08 -070093 "a=sendrecv\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -080094 "a=rtcp-mux\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -070095 "a=rtpmap:120 VP8/90000\r\n"
96 "a=ssrc:2 cname:stream1\r\n"
97 "a=ssrc:2 mslabel:stream1\r\n"
98 "a=ssrc:2 label:videotrack0\r\n";
99
zhihuang81c3a032016-11-17 12:06:24 -0800100// Reference SDP with a MediaStream with label "stream1" and audio track with
101// id "audio_1";
102static const char kSdpStringWithStream1AudioTrackOnly[] =
103 "v=0\r\n"
104 "o=- 0 0 IN IP4 127.0.0.1\r\n"
105 "s=-\r\n"
106 "t=0 0\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -0800107 "m=audio 1 RTP/AVPF 103\r\n"
zhihuang81c3a032016-11-17 12:06:24 -0800108 "a=ice-ufrag:e5785931\r\n"
109 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
110 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
111 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
zhihuang81c3a032016-11-17 12:06:24 -0800112 "a=mid:audio\r\n"
113 "a=sendrecv\r\n"
114 "a=rtpmap:103 ISAC/16000\r\n"
115 "a=ssrc:1 cname:stream1\r\n"
116 "a=ssrc:1 mslabel:stream1\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -0800117 "a=ssrc:1 label:audiotrack0\r\n"
118 "a=rtcp-mux\r\n";
zhihuang81c3a032016-11-17 12:06:24 -0800119
deadbeefab9b2d12015-10-14 11:33:11 -0700120// Reference SDP with two MediaStreams with label "stream1" and "stream2. Each
121// MediaStreams have one audio track and one video track.
122// This uses MSID.
123static const char kSdpStringWithStream1And2[] =
124 "v=0\r\n"
125 "o=- 0 0 IN IP4 127.0.0.1\r\n"
126 "s=-\r\n"
127 "t=0 0\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -0800128 "a=msid-semantic: WMS stream1 stream2\r\n"
129 "m=audio 1 RTP/AVPF 103\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700130 "a=ice-ufrag:e5785931\r\n"
131 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
132 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
133 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700134 "a=mid:audio\r\n"
deadbeef5e97fb52015-10-15 12:49:08 -0700135 "a=sendrecv\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -0800136 "a=rtcp-mux\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700137 "a=rtpmap:103 ISAC/16000\r\n"
138 "a=ssrc:1 cname:stream1\r\n"
139 "a=ssrc:1 msid:stream1 audiotrack0\r\n"
140 "a=ssrc:3 cname:stream2\r\n"
141 "a=ssrc:3 msid:stream2 audiotrack1\r\n"
142 "m=video 1 RTP/AVPF 120\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -0800143 "a=ice-ufrag:e5785931\r\n"
144 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
145 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
146 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700147 "a=mid:video\r\n"
deadbeef5e97fb52015-10-15 12:49:08 -0700148 "a=sendrecv\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -0800149 "a=rtcp-mux\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700150 "a=rtpmap:120 VP8/0\r\n"
151 "a=ssrc:2 cname:stream1\r\n"
152 "a=ssrc:2 msid:stream1 videotrack0\r\n"
153 "a=ssrc:4 cname:stream2\r\n"
154 "a=ssrc:4 msid:stream2 videotrack1\r\n";
155
156// Reference SDP without MediaStreams. Msid is not supported.
157static const char kSdpStringWithoutStreams[] =
158 "v=0\r\n"
159 "o=- 0 0 IN IP4 127.0.0.1\r\n"
160 "s=-\r\n"
161 "t=0 0\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -0800162 "m=audio 1 RTP/AVPF 103\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700163 "a=ice-ufrag:e5785931\r\n"
164 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
165 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
166 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700167 "a=mid:audio\r\n"
deadbeef5e97fb52015-10-15 12:49:08 -0700168 "a=sendrecv\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -0800169 "a=rtcp-mux\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700170 "a=rtpmap:103 ISAC/16000\r\n"
171 "m=video 1 RTP/AVPF 120\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -0800172 "a=ice-ufrag:e5785931\r\n"
173 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
174 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
175 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700176 "a=mid:video\r\n"
deadbeef5e97fb52015-10-15 12:49:08 -0700177 "a=sendrecv\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -0800178 "a=rtcp-mux\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700179 "a=rtpmap:120 VP8/90000\r\n";
180
181// Reference SDP without MediaStreams. Msid is supported.
182static const char kSdpStringWithMsidWithoutStreams[] =
183 "v=0\r\n"
184 "o=- 0 0 IN IP4 127.0.0.1\r\n"
185 "s=-\r\n"
186 "t=0 0\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -0800187 "a=msid-semantic: WMS\r\n"
188 "m=audio 1 RTP/AVPF 103\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700189 "a=ice-ufrag:e5785931\r\n"
190 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
191 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
192 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700193 "a=mid:audio\r\n"
deadbeef5e97fb52015-10-15 12:49:08 -0700194 "a=sendrecv\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -0800195 "a=rtcp-mux\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700196 "a=rtpmap:103 ISAC/16000\r\n"
197 "m=video 1 RTP/AVPF 120\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -0800198 "a=ice-ufrag:e5785931\r\n"
199 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
200 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
201 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700202 "a=mid:video\r\n"
deadbeef5e97fb52015-10-15 12:49:08 -0700203 "a=sendrecv\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -0800204 "a=rtcp-mux\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700205 "a=rtpmap:120 VP8/90000\r\n";
206
207// Reference SDP without MediaStreams and audio only.
208static const char kSdpStringWithoutStreamsAudioOnly[] =
209 "v=0\r\n"
210 "o=- 0 0 IN IP4 127.0.0.1\r\n"
211 "s=-\r\n"
212 "t=0 0\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -0800213 "m=audio 1 RTP/AVPF 103\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700214 "a=ice-ufrag:e5785931\r\n"
215 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
216 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
217 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700218 "a=mid:audio\r\n"
deadbeef5e97fb52015-10-15 12:49:08 -0700219 "a=sendrecv\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -0800220 "a=rtcp-mux\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700221 "a=rtpmap:103 ISAC/16000\r\n";
222
223// Reference SENDONLY SDP without MediaStreams. Msid is not supported.
224static const char kSdpStringSendOnlyWithoutStreams[] =
225 "v=0\r\n"
226 "o=- 0 0 IN IP4 127.0.0.1\r\n"
227 "s=-\r\n"
228 "t=0 0\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -0800229 "m=audio 1 RTP/AVPF 103\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700230 "a=ice-ufrag:e5785931\r\n"
231 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
232 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
233 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700234 "a=mid:audio\r\n"
deadbeef5e97fb52015-10-15 12:49:08 -0700235 "a=sendrecv\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700236 "a=sendonly\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -0800237 "a=rtcp-mux\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700238 "a=rtpmap:103 ISAC/16000\r\n"
239 "m=video 1 RTP/AVPF 120\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -0800240 "a=ice-ufrag:e5785931\r\n"
241 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
242 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
243 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700244 "a=mid:video\r\n"
deadbeef5e97fb52015-10-15 12:49:08 -0700245 "a=sendrecv\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700246 "a=sendonly\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -0800247 "a=rtcp-mux\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700248 "a=rtpmap:120 VP8/90000\r\n";
249
250static const char kSdpStringInit[] =
251 "v=0\r\n"
252 "o=- 0 0 IN IP4 127.0.0.1\r\n"
253 "s=-\r\n"
254 "t=0 0\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700255 "a=msid-semantic: WMS\r\n";
256
257static const char kSdpStringAudio[] =
258 "m=audio 1 RTP/AVPF 103\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -0800259 "a=ice-ufrag:e5785931\r\n"
260 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
261 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
262 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700263 "a=mid:audio\r\n"
deadbeef5e97fb52015-10-15 12:49:08 -0700264 "a=sendrecv\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -0800265 "a=rtcp-mux\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700266 "a=rtpmap:103 ISAC/16000\r\n";
267
268static const char kSdpStringVideo[] =
269 "m=video 1 RTP/AVPF 120\r\n"
deadbeefd1a38b52016-12-10 13:15:33 -0800270 "a=ice-ufrag:e5785931\r\n"
271 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
272 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
273 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700274 "a=mid:video\r\n"
deadbeef5e97fb52015-10-15 12:49:08 -0700275 "a=sendrecv\r\n"
zhihuang4dfb8ce2016-11-23 10:30:12 -0800276 "a=rtcp-mux\r\n"
deadbeefab9b2d12015-10-14 11:33:11 -0700277 "a=rtpmap:120 VP8/90000\r\n";
278
279static const char kSdpStringMs1Audio0[] =
280 "a=ssrc:1 cname:stream1\r\n"
281 "a=ssrc:1 msid:stream1 audiotrack0\r\n";
282
283static const char kSdpStringMs1Video0[] =
284 "a=ssrc:2 cname:stream1\r\n"
285 "a=ssrc:2 msid:stream1 videotrack0\r\n";
286
287static const char kSdpStringMs1Audio1[] =
288 "a=ssrc:3 cname:stream1\r\n"
289 "a=ssrc:3 msid:stream1 audiotrack1\r\n";
290
291static const char kSdpStringMs1Video1[] =
292 "a=ssrc:4 cname:stream1\r\n"
293 "a=ssrc:4 msid:stream1 videotrack1\r\n";
294
deadbeef8662f942017-01-20 21:20:51 -0800295static const char kDtlsSdesFallbackSdp[] =
296 "v=0\r\n"
297 "o=xxxxxx 7 2 IN IP4 0.0.0.0\r\n"
298 "s=-\r\n"
299 "c=IN IP4 0.0.0.0\r\n"
300 "t=0 0\r\n"
301 "a=group:BUNDLE audio\r\n"
302 "a=msid-semantic: WMS\r\n"
303 "m=audio 1 RTP/SAVPF 0\r\n"
304 "a=sendrecv\r\n"
305 "a=rtcp-mux\r\n"
306 "a=mid:audio\r\n"
307 "a=ssrc:1 cname:stream1\r\n"
308 "a=ssrc:1 mslabel:stream1\r\n"
309 "a=ssrc:1 label:audiotrack0\r\n"
310 "a=ice-ufrag:e5785931\r\n"
311 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
312 "a=rtpmap:0 pcmu/8000\r\n"
313 "a=fingerprint:sha-1 "
314 "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n"
315 "a=setup:actpass\r\n"
316 "a=crypto:1 AES_CM_128_HMAC_SHA1_32 "
317 "inline:NzB4d1BINUAvLEw6UzF3WSJ+PSdFcGdUJShpX1Zj|2^20|1:32 "
318 "dummy_session_params\r\n";
319
perkjd61bf802016-03-24 03:16:19 -0700320using ::testing::Exactly;
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -0700321using cricket::StreamParams;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000322using webrtc::AudioSourceInterface;
deadbeefab9b2d12015-10-14 11:33:11 -0700323using webrtc::AudioTrack;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000324using webrtc::AudioTrackInterface;
325using webrtc::DataBuffer;
326using webrtc::DataChannelInterface;
327using webrtc::FakeConstraints;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000328using webrtc::IceCandidateInterface;
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -0700329using webrtc::JsepSessionDescription;
deadbeefc80741f2015-10-22 13:14:45 -0700330using webrtc::MediaConstraintsInterface;
deadbeefab9b2d12015-10-14 11:33:11 -0700331using webrtc::MediaStream;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000332using webrtc::MediaStreamInterface;
333using webrtc::MediaStreamTrackInterface;
334using webrtc::MockCreateSessionDescriptionObserver;
335using webrtc::MockDataChannelObserver;
336using webrtc::MockSetSessionDescriptionObserver;
337using webrtc::MockStatsObserver;
perkjd61bf802016-03-24 03:16:19 -0700338using webrtc::NotifierInterface;
339using webrtc::ObserverInterface;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000340using webrtc::PeerConnectionInterface;
341using webrtc::PeerConnectionObserver;
deadbeef293e9262017-01-11 12:28:30 -0800342using webrtc::RTCError;
343using webrtc::RTCErrorType;
deadbeefab9b2d12015-10-14 11:33:11 -0700344using webrtc::RtpReceiverInterface;
345using webrtc::RtpSenderInterface;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000346using webrtc::SdpParseError;
347using webrtc::SessionDescriptionInterface;
deadbeefab9b2d12015-10-14 11:33:11 -0700348using webrtc::StreamCollection;
349using webrtc::StreamCollectionInterface;
perkja3ede6c2016-03-08 01:27:48 +0100350using webrtc::VideoTrackSourceInterface;
deadbeefab9b2d12015-10-14 11:33:11 -0700351using webrtc::VideoTrack;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000352using webrtc::VideoTrackInterface;
353
deadbeefab9b2d12015-10-14 11:33:11 -0700354typedef PeerConnectionInterface::RTCOfferAnswerOptions RTCOfferAnswerOptions;
355
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000356namespace {
357
358// Gets the first ssrc of given content type from the ContentInfo.
359bool GetFirstSsrc(const cricket::ContentInfo* content_info, int* ssrc) {
360 if (!content_info || !ssrc) {
361 return false;
362 }
363 const cricket::MediaContentDescription* media_desc =
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000364 static_cast<const cricket::MediaContentDescription*>(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000365 content_info->description);
366 if (!media_desc || media_desc->streams().empty()) {
367 return false;
368 }
369 *ssrc = media_desc->streams().begin()->first_ssrc();
370 return true;
371}
372
deadbeefd1a38b52016-12-10 13:15:33 -0800373// Get the ufrags out of an SDP blob. Useful for testing ICE restart
374// behavior.
375std::vector<std::string> GetUfrags(
376 const webrtc::SessionDescriptionInterface* desc) {
377 std::vector<std::string> ufrags;
378 for (const cricket::TransportInfo& info :
379 desc->description()->transport_infos()) {
380 ufrags.push_back(info.description.ice_ufrag);
381 }
382 return ufrags;
383}
384
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000385void SetSsrcToZero(std::string* sdp) {
386 const char kSdpSsrcAtribute[] = "a=ssrc:";
387 const char kSdpSsrcAtributeZero[] = "a=ssrc:0";
388 size_t ssrc_pos = 0;
389 while ((ssrc_pos = sdp->find(kSdpSsrcAtribute, ssrc_pos)) !=
390 std::string::npos) {
391 size_t end_ssrc = sdp->find(" ", ssrc_pos);
392 sdp->replace(ssrc_pos, end_ssrc - ssrc_pos, kSdpSsrcAtributeZero);
393 ssrc_pos = end_ssrc;
394 }
395}
396
deadbeefab9b2d12015-10-14 11:33:11 -0700397// Check if |streams| contains the specified track.
398bool ContainsTrack(const std::vector<cricket::StreamParams>& streams,
399 const std::string& stream_label,
400 const std::string& track_id) {
401 for (const cricket::StreamParams& params : streams) {
402 if (params.sync_label == stream_label && params.id == track_id) {
403 return true;
404 }
405 }
406 return false;
407}
408
409// Check if |senders| contains the specified sender, by id.
410bool ContainsSender(
411 const std::vector<rtc::scoped_refptr<RtpSenderInterface>>& senders,
412 const std::string& id) {
413 for (const auto& sender : senders) {
414 if (sender->id() == id) {
415 return true;
416 }
417 }
418 return false;
419}
420
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -0700421// Check if |senders| contains the specified sender, by id and stream id.
422bool ContainsSender(
423 const std::vector<rtc::scoped_refptr<RtpSenderInterface>>& senders,
424 const std::string& id,
425 const std::string& stream_id) {
426 for (const auto& sender : senders) {
deadbeefa601f5c2016-06-06 14:27:39 -0700427 if (sender->id() == id && sender->stream_ids()[0] == stream_id) {
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -0700428 return true;
429 }
430 }
431 return false;
432}
433
deadbeefab9b2d12015-10-14 11:33:11 -0700434// Create a collection of streams.
435// CreateStreamCollection(1) creates a collection that
436// correspond to kSdpStringWithStream1.
437// CreateStreamCollection(2) correspond to kSdpStringWithStream1And2.
438rtc::scoped_refptr<StreamCollection> CreateStreamCollection(
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -0700439 int number_of_streams,
440 int tracks_per_stream) {
deadbeefab9b2d12015-10-14 11:33:11 -0700441 rtc::scoped_refptr<StreamCollection> local_collection(
442 StreamCollection::Create());
443
444 for (int i = 0; i < number_of_streams; ++i) {
445 rtc::scoped_refptr<webrtc::MediaStreamInterface> stream(
446 webrtc::MediaStream::Create(kStreams[i]));
447
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -0700448 for (int j = 0; j < tracks_per_stream; ++j) {
449 // Add a local audio track.
450 rtc::scoped_refptr<webrtc::AudioTrackInterface> audio_track(
451 webrtc::AudioTrack::Create(kAudioTracks[i * tracks_per_stream + j],
452 nullptr));
453 stream->AddTrack(audio_track);
deadbeefab9b2d12015-10-14 11:33:11 -0700454
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -0700455 // Add a local video track.
456 rtc::scoped_refptr<webrtc::VideoTrackInterface> video_track(
457 webrtc::VideoTrack::Create(kVideoTracks[i * tracks_per_stream + j],
458 webrtc::FakeVideoTrackSource::Create()));
459 stream->AddTrack(video_track);
460 }
deadbeefab9b2d12015-10-14 11:33:11 -0700461
462 local_collection->AddStream(stream);
463 }
464 return local_collection;
465}
466
467// Check equality of StreamCollections.
468bool CompareStreamCollections(StreamCollectionInterface* s1,
469 StreamCollectionInterface* s2) {
470 if (s1 == nullptr || s2 == nullptr || s1->count() != s2->count()) {
471 return false;
472 }
473
474 for (size_t i = 0; i != s1->count(); ++i) {
475 if (s1->at(i)->label() != s2->at(i)->label()) {
476 return false;
477 }
478 webrtc::AudioTrackVector audio_tracks1 = s1->at(i)->GetAudioTracks();
479 webrtc::AudioTrackVector audio_tracks2 = s2->at(i)->GetAudioTracks();
480 webrtc::VideoTrackVector video_tracks1 = s1->at(i)->GetVideoTracks();
481 webrtc::VideoTrackVector video_tracks2 = s2->at(i)->GetVideoTracks();
482
483 if (audio_tracks1.size() != audio_tracks2.size()) {
484 return false;
485 }
486 for (size_t j = 0; j != audio_tracks1.size(); ++j) {
487 if (audio_tracks1[j]->id() != audio_tracks2[j]->id()) {
488 return false;
489 }
490 }
491 if (video_tracks1.size() != video_tracks2.size()) {
492 return false;
493 }
494 for (size_t j = 0; j != video_tracks1.size(); ++j) {
495 if (video_tracks1[j]->id() != video_tracks2[j]->id()) {
496 return false;
497 }
498 }
499 }
500 return true;
501}
502
perkjd61bf802016-03-24 03:16:19 -0700503// Helper class to test Observer.
504class MockTrackObserver : public ObserverInterface {
505 public:
506 explicit MockTrackObserver(NotifierInterface* notifier)
507 : notifier_(notifier) {
508 notifier_->RegisterObserver(this);
509 }
510
511 ~MockTrackObserver() { Unregister(); }
512
513 void Unregister() {
514 if (notifier_) {
515 notifier_->UnregisterObserver(this);
516 notifier_ = nullptr;
517 }
518 }
519
520 MOCK_METHOD0(OnChanged, void());
521
522 private:
523 NotifierInterface* notifier_;
524};
525
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000526class MockPeerConnectionObserver : public PeerConnectionObserver {
527 public:
kjellander71a1b612016-11-07 01:18:08 -0800528 // We need these using declarations because there are two versions of each of
529 // the below methods and we only override one of them.
530 // TODO(deadbeef): Remove once there's only one version of the methods.
531 using PeerConnectionObserver::OnAddStream;
532 using PeerConnectionObserver::OnRemoveStream;
533 using PeerConnectionObserver::OnDataChannel;
534
deadbeefab9b2d12015-10-14 11:33:11 -0700535 MockPeerConnectionObserver() : remote_streams_(StreamCollection::Create()) {}
Henrik Kjellander3fe372d2016-05-12 08:10:52 +0200536 virtual ~MockPeerConnectionObserver() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000537 }
538 void SetPeerConnectionInterface(PeerConnectionInterface* pc) {
539 pc_ = pc;
540 if (pc) {
541 state_ = pc_->signaling_state();
542 }
543 }
nisseef8b61e2016-04-29 06:09:15 -0700544 void OnSignalingChange(
545 PeerConnectionInterface::SignalingState new_state) override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000546 EXPECT_EQ(pc_->signaling_state(), new_state);
547 state_ = new_state;
548 }
549 // TODO(bemasc): Remove this once callers transition to OnIceGatheringChange.
550 virtual void OnStateChange(StateType state_changed) {
551 if (pc_.get() == NULL)
552 return;
553 switch (state_changed) {
554 case kSignalingState:
555 // OnSignalingChange and OnStateChange(kSignalingState) should always
556 // be called approximately simultaneously. To ease testing, we require
557 // that they always be called in that order. This check verifies
558 // that OnSignalingChange has just been called.
559 EXPECT_EQ(pc_->signaling_state(), state_);
560 break;
561 case kIceState:
562 ADD_FAILURE();
563 break;
564 default:
565 ADD_FAILURE();
566 break;
567 }
568 }
deadbeefab9b2d12015-10-14 11:33:11 -0700569
570 MediaStreamInterface* RemoteStream(const std::string& label) {
571 return remote_streams_->find(label);
572 }
573 StreamCollectionInterface* remote_streams() const { return remote_streams_; }
Taylor Brandstetter98cde262016-05-31 13:02:21 -0700574 void OnAddStream(rtc::scoped_refptr<MediaStreamInterface> stream) override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000575 last_added_stream_ = stream;
deadbeefab9b2d12015-10-14 11:33:11 -0700576 remote_streams_->AddStream(stream);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000577 }
Taylor Brandstetter98cde262016-05-31 13:02:21 -0700578 void OnRemoveStream(
579 rtc::scoped_refptr<MediaStreamInterface> stream) override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000580 last_removed_stream_ = stream;
deadbeefab9b2d12015-10-14 11:33:11 -0700581 remote_streams_->RemoveStream(stream);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000582 }
perkjdfb769d2016-02-09 03:09:43 -0800583 void OnRenegotiationNeeded() override { renegotiation_needed_ = true; }
Taylor Brandstetter98cde262016-05-31 13:02:21 -0700584 void OnDataChannel(
585 rtc::scoped_refptr<DataChannelInterface> data_channel) override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000586 last_datachannel_ = data_channel;
587 }
588
perkjdfb769d2016-02-09 03:09:43 -0800589 void OnIceConnectionChange(
590 PeerConnectionInterface::IceConnectionState new_state) override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000591 EXPECT_EQ(pc_->ice_connection_state(), new_state);
zhihuang81c3a032016-11-17 12:06:24 -0800592 callback_triggered_ = true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000593 }
perkjdfb769d2016-02-09 03:09:43 -0800594 void OnIceGatheringChange(
595 PeerConnectionInterface::IceGatheringState new_state) override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000596 EXPECT_EQ(pc_->ice_gathering_state(), new_state);
perkjdfb769d2016-02-09 03:09:43 -0800597 ice_complete_ = new_state == PeerConnectionInterface::kIceGatheringComplete;
zhihuang81c3a032016-11-17 12:06:24 -0800598 callback_triggered_ = true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000599 }
perkjdfb769d2016-02-09 03:09:43 -0800600 void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000601 EXPECT_NE(PeerConnectionInterface::kIceGatheringNew,
602 pc_->ice_gathering_state());
603
604 std::string sdp;
605 EXPECT_TRUE(candidate->ToString(&sdp));
606 EXPECT_LT(0u, sdp.size());
607 last_candidate_.reset(webrtc::CreateIceCandidate(candidate->sdp_mid(),
608 candidate->sdp_mline_index(), sdp, NULL));
609 EXPECT_TRUE(last_candidate_.get() != NULL);
zhihuang81c3a032016-11-17 12:06:24 -0800610 callback_triggered_ = true;
zhihuang29ff8442016-07-27 11:07:25 -0700611 }
612
613 void OnIceCandidatesRemoved(
614 const std::vector<cricket::Candidate>& candidates) override {
zhihuang81c3a032016-11-17 12:06:24 -0800615 callback_triggered_ = true;
zhihuang29ff8442016-07-27 11:07:25 -0700616 }
617
618 void OnIceConnectionReceivingChange(bool receiving) override {
zhihuang81c3a032016-11-17 12:06:24 -0800619 callback_triggered_ = true;
620 }
621
zhihuangc63b8942016-12-02 15:41:10 -0800622 void OnAddTrack(
623 rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver,
624 const std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>>&
625 streams) override {
zhihuang81c3a032016-11-17 12:06:24 -0800626 EXPECT_TRUE(receiver != nullptr);
627 num_added_tracks_++;
628 last_added_track_label_ = receiver->id();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000629 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000630
631 // Returns the label of the last added stream.
632 // Empty string if no stream have been added.
633 std::string GetLastAddedStreamLabel() {
634 if (last_added_stream_.get())
635 return last_added_stream_->label();
636 return "";
637 }
638 std::string GetLastRemovedStreamLabel() {
639 if (last_removed_stream_.get())
640 return last_removed_stream_->label();
641 return "";
642 }
643
zhihuang9763d562016-08-05 11:14:50 -0700644 rtc::scoped_refptr<PeerConnectionInterface> pc_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000645 PeerConnectionInterface::SignalingState state_;
kwibergd1fe2812016-04-27 06:47:29 -0700646 std::unique_ptr<IceCandidateInterface> last_candidate_;
zhihuang9763d562016-08-05 11:14:50 -0700647 rtc::scoped_refptr<DataChannelInterface> last_datachannel_;
deadbeefab9b2d12015-10-14 11:33:11 -0700648 rtc::scoped_refptr<StreamCollection> remote_streams_;
649 bool renegotiation_needed_ = false;
650 bool ice_complete_ = false;
zhihuang81c3a032016-11-17 12:06:24 -0800651 bool callback_triggered_ = false;
652 int num_added_tracks_ = 0;
653 std::string last_added_track_label_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000654
655 private:
zhihuang9763d562016-08-05 11:14:50 -0700656 rtc::scoped_refptr<MediaStreamInterface> last_added_stream_;
657 rtc::scoped_refptr<MediaStreamInterface> last_removed_stream_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000658};
659
660} // namespace
deadbeefab9b2d12015-10-14 11:33:11 -0700661
zhihuang29ff8442016-07-27 11:07:25 -0700662// The PeerConnectionMediaConfig tests below verify that configuration
663// and constraints are propagated into the MediaConfig passed to
664// CreateMediaController. These settings are intended for MediaChannel
665// constructors, but that is not exercised by these unittest.
666class PeerConnectionFactoryForTest : public webrtc::PeerConnectionFactory {
667 public:
668 webrtc::MediaControllerInterface* CreateMediaController(
skvlad11a9cbf2016-10-07 11:53:05 -0700669 const cricket::MediaConfig& config,
670 webrtc::RtcEventLog* event_log) const override {
zhihuang29ff8442016-07-27 11:07:25 -0700671 create_media_controller_called_ = true;
672 create_media_controller_config_ = config;
673
674 webrtc::MediaControllerInterface* mc =
skvlad11a9cbf2016-10-07 11:53:05 -0700675 PeerConnectionFactory::CreateMediaController(config, event_log);
zhihuang29ff8442016-07-27 11:07:25 -0700676 EXPECT_TRUE(mc != nullptr);
677 return mc;
678 }
679
680 cricket::TransportController* CreateTransportController(
Honghai Zhangbfd398c2016-08-30 22:07:42 -0700681 cricket::PortAllocator* port_allocator,
682 bool redetermine_role_on_ice_restart) override {
zhihuang29ff8442016-07-27 11:07:25 -0700683 transport_controller = new cricket::TransportController(
Honghai Zhangbfd398c2016-08-30 22:07:42 -0700684 rtc::Thread::Current(), rtc::Thread::Current(), port_allocator,
685 redetermine_role_on_ice_restart);
zhihuang29ff8442016-07-27 11:07:25 -0700686 return transport_controller;
687 }
688
689 cricket::TransportController* transport_controller;
690 // Mutable, so they can be modified in the above const-declared method.
691 mutable bool create_media_controller_called_ = false;
692 mutable cricket::MediaConfig create_media_controller_config_;
693};
694
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000695class PeerConnectionInterfaceTest : public testing::Test {
696 protected:
phoglund37ebcf02016-01-08 05:04:57 -0800697 PeerConnectionInterfaceTest() {
698#ifdef WEBRTC_ANDROID
699 webrtc::InitializeAndroidObjects();
700#endif
701 }
702
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000703 virtual void SetUp() {
704 pc_factory_ = webrtc::CreatePeerConnectionFactory(
danilchape9021a32016-05-17 01:52:02 -0700705 rtc::Thread::Current(), rtc::Thread::Current(), rtc::Thread::Current(),
706 nullptr, nullptr, nullptr);
707 ASSERT_TRUE(pc_factory_);
zhihuang29ff8442016-07-27 11:07:25 -0700708 pc_factory_for_test_ =
709 new rtc::RefCountedObject<PeerConnectionFactoryForTest>();
710 pc_factory_for_test_->Initialize();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000711 }
712
713 void CreatePeerConnection() {
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700714 CreatePeerConnection(PeerConnectionInterface::RTCConfiguration(), nullptr);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000715 }
716
deadbeef293e9262017-01-11 12:28:30 -0800717 // DTLS does not work in a loopback call, so is disabled for most of the
718 // tests in this file.
719 void CreatePeerConnectionWithoutDtls() {
720 FakeConstraints no_dtls_constraints;
721 no_dtls_constraints.AddMandatory(
722 webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, false);
723
724 CreatePeerConnection(PeerConnectionInterface::RTCConfiguration(),
725 &no_dtls_constraints);
726 }
727
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000728 void CreatePeerConnection(webrtc::MediaConstraintsInterface* constraints) {
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700729 CreatePeerConnection(PeerConnectionInterface::RTCConfiguration(),
730 constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000731 }
732
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700733 void CreatePeerConnectionWithIceTransportsType(
734 PeerConnectionInterface::IceTransportsType type) {
735 PeerConnectionInterface::RTCConfiguration config;
736 config.type = type;
737 return CreatePeerConnection(config, nullptr);
738 }
739
740 void CreatePeerConnectionWithIceServer(const std::string& uri,
741 const std::string& password) {
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800742 PeerConnectionInterface::RTCConfiguration config;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000743 PeerConnectionInterface::IceServer server;
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700744 server.uri = uri;
745 server.password = password;
746 config.servers.push_back(server);
747 CreatePeerConnection(config, nullptr);
748 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000749
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700750 void CreatePeerConnection(PeerConnectionInterface::RTCConfiguration config,
751 webrtc::MediaConstraintsInterface* constraints) {
kwibergd1fe2812016-04-27 06:47:29 -0700752 std::unique_ptr<cricket::FakePortAllocator> port_allocator(
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800753 new cricket::FakePortAllocator(rtc::Thread::Current(), nullptr));
754 port_allocator_ = port_allocator.get();
jiayl@webrtc.orga576faf2014-01-29 17:45:53 +0000755
Henrik Boströmd79599d2016-06-01 13:58:50 +0200756 std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator;
jiayl@webrtc.orga576faf2014-01-29 17:45:53 +0000757 bool dtls;
758 if (FindConstraint(constraints,
759 webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
760 &dtls,
Henrik Boström5e56c592015-08-11 10:33:13 +0200761 nullptr) && dtls) {
deadbeef8662f942017-01-20 21:20:51 -0800762 fake_certificate_generator_ = new FakeRTCCertificateGenerator();
763 cert_generator.reset(fake_certificate_generator_);
jiayl@webrtc.orga576faf2014-01-29 17:45:53 +0000764 }
Henrik Boströmd79599d2016-06-01 13:58:50 +0200765 pc_ = pc_factory_->CreatePeerConnection(
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800766 config, constraints, std::move(port_allocator),
Henrik Boströmd79599d2016-06-01 13:58:50 +0200767 std::move(cert_generator), &observer_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000768 ASSERT_TRUE(pc_.get() != NULL);
769 observer_.SetPeerConnectionInterface(pc_.get());
770 EXPECT_EQ(PeerConnectionInterface::kStable, observer_.state_);
771 }
772
deadbeef0a6c4ca2015-10-06 11:38:28 -0700773 void CreatePeerConnectionExpectFail(const std::string& uri) {
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800774 PeerConnectionInterface::RTCConfiguration config;
deadbeef0a6c4ca2015-10-06 11:38:28 -0700775 PeerConnectionInterface::IceServer server;
deadbeef0a6c4ca2015-10-06 11:38:28 -0700776 server.uri = uri;
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800777 config.servers.push_back(server);
deadbeef0a6c4ca2015-10-06 11:38:28 -0700778
zhihuang9763d562016-08-05 11:14:50 -0700779 rtc::scoped_refptr<PeerConnectionInterface> pc;
hbosd7973cc2016-05-27 06:08:53 -0700780 pc = pc_factory_->CreatePeerConnection(config, nullptr, nullptr, nullptr,
781 &observer_);
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800782 EXPECT_EQ(nullptr, pc);
deadbeef0a6c4ca2015-10-06 11:38:28 -0700783 }
784
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000785 void CreatePeerConnectionWithDifferentConfigurations() {
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700786 CreatePeerConnectionWithIceServer(kStunAddressOnly, "");
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800787 EXPECT_EQ(1u, port_allocator_->stun_servers().size());
788 EXPECT_EQ(0u, port_allocator_->turn_servers().size());
789 EXPECT_EQ("address", port_allocator_->stun_servers().begin()->hostname());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000790 EXPECT_EQ(kDefaultStunPort,
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800791 port_allocator_->stun_servers().begin()->port());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000792
deadbeef0a6c4ca2015-10-06 11:38:28 -0700793 CreatePeerConnectionExpectFail(kStunInvalidPort);
794 CreatePeerConnectionExpectFail(kStunAddressPortAndMore1);
795 CreatePeerConnectionExpectFail(kStunAddressPortAndMore2);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000796
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700797 CreatePeerConnectionWithIceServer(kTurnIceServerUri, kTurnPassword);
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800798 EXPECT_EQ(0u, port_allocator_->stun_servers().size());
799 EXPECT_EQ(1u, port_allocator_->turn_servers().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000800 EXPECT_EQ(kTurnUsername,
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800801 port_allocator_->turn_servers()[0].credentials.username);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000802 EXPECT_EQ(kTurnPassword,
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800803 port_allocator_->turn_servers()[0].credentials.password);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000804 EXPECT_EQ(kTurnHostname,
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800805 port_allocator_->turn_servers()[0].ports[0].address.hostname());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000806 }
807
808 void ReleasePeerConnection() {
809 pc_ = NULL;
810 observer_.SetPeerConnectionInterface(NULL);
811 }
812
deadbeefab9b2d12015-10-14 11:33:11 -0700813 void AddVideoStream(const std::string& label) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000814 // Create a local stream.
zhihuang9763d562016-08-05 11:14:50 -0700815 rtc::scoped_refptr<MediaStreamInterface> stream(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000816 pc_factory_->CreateLocalMediaStream(label));
zhihuang9763d562016-08-05 11:14:50 -0700817 rtc::scoped_refptr<VideoTrackSourceInterface> video_source(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000818 pc_factory_->CreateVideoSource(new cricket::FakeVideoCapturer(), NULL));
zhihuang9763d562016-08-05 11:14:50 -0700819 rtc::scoped_refptr<VideoTrackInterface> video_track(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000820 pc_factory_->CreateVideoTrack(label + "v0", video_source));
821 stream->AddTrack(video_track.get());
perkj@webrtc.orgc2dd5ee2014-11-04 11:31:29 +0000822 EXPECT_TRUE(pc_->AddStream(stream));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000823 EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout);
824 observer_.renegotiation_needed_ = false;
825 }
826
827 void AddVoiceStream(const std::string& label) {
828 // Create a local stream.
zhihuang9763d562016-08-05 11:14:50 -0700829 rtc::scoped_refptr<MediaStreamInterface> stream(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000830 pc_factory_->CreateLocalMediaStream(label));
zhihuang9763d562016-08-05 11:14:50 -0700831 rtc::scoped_refptr<AudioTrackInterface> audio_track(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000832 pc_factory_->CreateAudioTrack(label + "a0", NULL));
833 stream->AddTrack(audio_track.get());
perkj@webrtc.orgc2dd5ee2014-11-04 11:31:29 +0000834 EXPECT_TRUE(pc_->AddStream(stream));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000835 EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout);
836 observer_.renegotiation_needed_ = false;
837 }
838
839 void AddAudioVideoStream(const std::string& stream_label,
840 const std::string& audio_track_label,
841 const std::string& video_track_label) {
842 // Create a local stream.
zhihuang9763d562016-08-05 11:14:50 -0700843 rtc::scoped_refptr<MediaStreamInterface> stream(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000844 pc_factory_->CreateLocalMediaStream(stream_label));
zhihuang9763d562016-08-05 11:14:50 -0700845 rtc::scoped_refptr<AudioTrackInterface> audio_track(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000846 pc_factory_->CreateAudioTrack(
847 audio_track_label, static_cast<AudioSourceInterface*>(NULL)));
848 stream->AddTrack(audio_track.get());
zhihuang9763d562016-08-05 11:14:50 -0700849 rtc::scoped_refptr<VideoTrackInterface> video_track(
nisseaf510af2016-03-21 08:20:42 -0700850 pc_factory_->CreateVideoTrack(
851 video_track_label,
852 pc_factory_->CreateVideoSource(new cricket::FakeVideoCapturer())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000853 stream->AddTrack(video_track.get());
perkj@webrtc.orgc2dd5ee2014-11-04 11:31:29 +0000854 EXPECT_TRUE(pc_->AddStream(stream));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000855 EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout);
856 observer_.renegotiation_needed_ = false;
857 }
858
kwibergd1fe2812016-04-27 06:47:29 -0700859 bool DoCreateOfferAnswer(std::unique_ptr<SessionDescriptionInterface>* desc,
deadbeefc80741f2015-10-22 13:14:45 -0700860 bool offer,
861 MediaConstraintsInterface* constraints) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000862 rtc::scoped_refptr<MockCreateSessionDescriptionObserver>
863 observer(new rtc::RefCountedObject<
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000864 MockCreateSessionDescriptionObserver>());
865 if (offer) {
deadbeefc80741f2015-10-22 13:14:45 -0700866 pc_->CreateOffer(observer, constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000867 } else {
deadbeefc80741f2015-10-22 13:14:45 -0700868 pc_->CreateAnswer(observer, constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000869 }
870 EXPECT_EQ_WAIT(true, observer->called(), kTimeout);
kwiberg2bbff992016-03-16 11:03:04 -0700871 desc->reset(observer->release_desc());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000872 return observer->result();
873 }
874
kwibergd1fe2812016-04-27 06:47:29 -0700875 bool DoCreateOffer(std::unique_ptr<SessionDescriptionInterface>* desc,
deadbeefc80741f2015-10-22 13:14:45 -0700876 MediaConstraintsInterface* constraints) {
877 return DoCreateOfferAnswer(desc, true, constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000878 }
879
kwibergd1fe2812016-04-27 06:47:29 -0700880 bool DoCreateAnswer(std::unique_ptr<SessionDescriptionInterface>* desc,
deadbeefc80741f2015-10-22 13:14:45 -0700881 MediaConstraintsInterface* constraints) {
882 return DoCreateOfferAnswer(desc, false, constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000883 }
884
885 bool DoSetSessionDescription(SessionDescriptionInterface* desc, bool local) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000886 rtc::scoped_refptr<MockSetSessionDescriptionObserver>
887 observer(new rtc::RefCountedObject<
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000888 MockSetSessionDescriptionObserver>());
889 if (local) {
890 pc_->SetLocalDescription(observer, desc);
891 } else {
892 pc_->SetRemoteDescription(observer, desc);
893 }
zhihuang29ff8442016-07-27 11:07:25 -0700894 if (pc_->signaling_state() != PeerConnectionInterface::kClosed) {
895 EXPECT_EQ_WAIT(true, observer->called(), kTimeout);
896 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000897 return observer->result();
898 }
899
900 bool DoSetLocalDescription(SessionDescriptionInterface* desc) {
901 return DoSetSessionDescription(desc, true);
902 }
903
904 bool DoSetRemoteDescription(SessionDescriptionInterface* desc) {
905 return DoSetSessionDescription(desc, false);
906 }
907
908 // Calls PeerConnection::GetStats and check the return value.
909 // It does not verify the values in the StatReports since a RTCP packet might
910 // be required.
911 bool DoGetStats(MediaStreamTrackInterface* track) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000912 rtc::scoped_refptr<MockStatsObserver> observer(
913 new rtc::RefCountedObject<MockStatsObserver>());
jiayl@webrtc.orgdb41b4d2014-03-03 21:30:06 +0000914 if (!pc_->GetStats(
915 observer, track, PeerConnectionInterface::kStatsOutputLevelStandard))
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000916 return false;
917 EXPECT_TRUE_WAIT(observer->called(), kTimeout);
918 return observer->called();
919 }
920
921 void InitiateCall() {
deadbeef293e9262017-01-11 12:28:30 -0800922 CreatePeerConnectionWithoutDtls();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000923 // Create a local stream with audio&video tracks.
924 AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label");
925 CreateOfferReceiveAnswer();
926 }
927
928 // Verify that RTP Header extensions has been negotiated for audio and video.
929 void VerifyRemoteRtpHeaderExtensions() {
930 const cricket::MediaContentDescription* desc =
931 cricket::GetFirstAudioContentDescription(
932 pc_->remote_description()->description());
933 ASSERT_TRUE(desc != NULL);
934 EXPECT_GT(desc->rtp_header_extensions().size(), 0u);
935
936 desc = cricket::GetFirstVideoContentDescription(
937 pc_->remote_description()->description());
938 ASSERT_TRUE(desc != NULL);
939 EXPECT_GT(desc->rtp_header_extensions().size(), 0u);
940 }
941
942 void CreateOfferAsRemoteDescription() {
kwibergd1fe2812016-04-27 06:47:29 -0700943 std::unique_ptr<SessionDescriptionInterface> offer;
kwiberg2bbff992016-03-16 11:03:04 -0700944 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000945 std::string sdp;
946 EXPECT_TRUE(offer->ToString(&sdp));
947 SessionDescriptionInterface* remote_offer =
948 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer,
949 sdp, NULL);
950 EXPECT_TRUE(DoSetRemoteDescription(remote_offer));
951 EXPECT_EQ(PeerConnectionInterface::kHaveRemoteOffer, observer_.state_);
952 }
953
deadbeefab9b2d12015-10-14 11:33:11 -0700954 void CreateAndSetRemoteOffer(const std::string& sdp) {
955 SessionDescriptionInterface* remote_offer =
956 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer,
957 sdp, nullptr);
958 EXPECT_TRUE(DoSetRemoteDescription(remote_offer));
959 EXPECT_EQ(PeerConnectionInterface::kHaveRemoteOffer, observer_.state_);
960 }
961
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000962 void CreateAnswerAsLocalDescription() {
kwibergd1fe2812016-04-27 06:47:29 -0700963 std::unique_ptr<SessionDescriptionInterface> answer;
kwiberg2bbff992016-03-16 11:03:04 -0700964 ASSERT_TRUE(DoCreateAnswer(&answer, nullptr));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000965
966 // TODO(perkj): Currently SetLocalDescription fails if any parameters in an
967 // audio codec change, even if the parameter has nothing to do with
968 // receiving. Not all parameters are serialized to SDP.
969 // Since CreatePrAnswerAsLocalDescription serialize/deserialize
970 // the SessionDescription, it is necessary to do that here to in order to
971 // get ReceiveOfferCreatePrAnswerAndAnswer and RenegotiateAudioOnly to pass.
972 // https://code.google.com/p/webrtc/issues/detail?id=1356
973 std::string sdp;
974 EXPECT_TRUE(answer->ToString(&sdp));
975 SessionDescriptionInterface* new_answer =
976 webrtc::CreateSessionDescription(SessionDescriptionInterface::kAnswer,
977 sdp, NULL);
978 EXPECT_TRUE(DoSetLocalDescription(new_answer));
979 EXPECT_EQ(PeerConnectionInterface::kStable, observer_.state_);
980 }
981
982 void CreatePrAnswerAsLocalDescription() {
kwibergd1fe2812016-04-27 06:47:29 -0700983 std::unique_ptr<SessionDescriptionInterface> answer;
kwiberg2bbff992016-03-16 11:03:04 -0700984 ASSERT_TRUE(DoCreateAnswer(&answer, nullptr));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000985
986 std::string sdp;
987 EXPECT_TRUE(answer->ToString(&sdp));
988 SessionDescriptionInterface* pr_answer =
989 webrtc::CreateSessionDescription(SessionDescriptionInterface::kPrAnswer,
990 sdp, NULL);
991 EXPECT_TRUE(DoSetLocalDescription(pr_answer));
992 EXPECT_EQ(PeerConnectionInterface::kHaveLocalPrAnswer, observer_.state_);
993 }
994
995 void CreateOfferReceiveAnswer() {
996 CreateOfferAsLocalDescription();
997 std::string sdp;
998 EXPECT_TRUE(pc_->local_description()->ToString(&sdp));
999 CreateAnswerAsRemoteDescription(sdp);
1000 }
1001
1002 void CreateOfferAsLocalDescription() {
kwibergd1fe2812016-04-27 06:47:29 -07001003 std::unique_ptr<SessionDescriptionInterface> offer;
kwiberg2bbff992016-03-16 11:03:04 -07001004 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001005 // TODO(perkj): Currently SetLocalDescription fails if any parameters in an
1006 // audio codec change, even if the parameter has nothing to do with
1007 // receiving. Not all parameters are serialized to SDP.
1008 // Since CreatePrAnswerAsLocalDescription serialize/deserialize
1009 // the SessionDescription, it is necessary to do that here to in order to
1010 // get ReceiveOfferCreatePrAnswerAndAnswer and RenegotiateAudioOnly to pass.
1011 // https://code.google.com/p/webrtc/issues/detail?id=1356
1012 std::string sdp;
1013 EXPECT_TRUE(offer->ToString(&sdp));
1014 SessionDescriptionInterface* new_offer =
1015 webrtc::CreateSessionDescription(
1016 SessionDescriptionInterface::kOffer,
1017 sdp, NULL);
1018
1019 EXPECT_TRUE(DoSetLocalDescription(new_offer));
1020 EXPECT_EQ(PeerConnectionInterface::kHaveLocalOffer, observer_.state_);
mallinath@webrtc.org68cbd012014-01-22 00:16:46 +00001021 // Wait for the ice_complete message, so that SDP will have candidates.
1022 EXPECT_TRUE_WAIT(observer_.ice_complete_, kTimeout);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001023 }
1024
deadbeefab9b2d12015-10-14 11:33:11 -07001025 void CreateAnswerAsRemoteDescription(const std::string& sdp) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001026 webrtc::JsepSessionDescription* answer = new webrtc::JsepSessionDescription(
1027 SessionDescriptionInterface::kAnswer);
deadbeefab9b2d12015-10-14 11:33:11 -07001028 EXPECT_TRUE(answer->Initialize(sdp, NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001029 EXPECT_TRUE(DoSetRemoteDescription(answer));
1030 EXPECT_EQ(PeerConnectionInterface::kStable, observer_.state_);
1031 }
1032
deadbeefab9b2d12015-10-14 11:33:11 -07001033 void CreatePrAnswerAndAnswerAsRemoteDescription(const std::string& sdp) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001034 webrtc::JsepSessionDescription* pr_answer =
1035 new webrtc::JsepSessionDescription(
1036 SessionDescriptionInterface::kPrAnswer);
deadbeefab9b2d12015-10-14 11:33:11 -07001037 EXPECT_TRUE(pr_answer->Initialize(sdp, NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001038 EXPECT_TRUE(DoSetRemoteDescription(pr_answer));
1039 EXPECT_EQ(PeerConnectionInterface::kHaveRemotePrAnswer, observer_.state_);
1040 webrtc::JsepSessionDescription* answer =
1041 new webrtc::JsepSessionDescription(
1042 SessionDescriptionInterface::kAnswer);
deadbeefab9b2d12015-10-14 11:33:11 -07001043 EXPECT_TRUE(answer->Initialize(sdp, NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001044 EXPECT_TRUE(DoSetRemoteDescription(answer));
1045 EXPECT_EQ(PeerConnectionInterface::kStable, observer_.state_);
1046 }
1047
1048 // Help function used for waiting until a the last signaled remote stream has
1049 // the same label as |stream_label|. In a few of the tests in this file we
1050 // answer with the same session description as we offer and thus we can
1051 // check if OnAddStream have been called with the same stream as we offer to
1052 // send.
1053 void WaitAndVerifyOnAddStream(const std::string& stream_label) {
1054 EXPECT_EQ_WAIT(stream_label, observer_.GetLastAddedStreamLabel(), kTimeout);
1055 }
1056
1057 // Creates an offer and applies it as a local session description.
1058 // Creates an answer with the same SDP an the offer but removes all lines
1059 // that start with a:ssrc"
1060 void CreateOfferReceiveAnswerWithoutSsrc() {
1061 CreateOfferAsLocalDescription();
1062 std::string sdp;
1063 EXPECT_TRUE(pc_->local_description()->ToString(&sdp));
1064 SetSsrcToZero(&sdp);
1065 CreateAnswerAsRemoteDescription(sdp);
1066 }
1067
deadbeefab9b2d12015-10-14 11:33:11 -07001068 // This function creates a MediaStream with label kStreams[0] and
1069 // |number_of_audio_tracks| and |number_of_video_tracks| tracks and the
1070 // corresponding SessionDescriptionInterface. The SessionDescriptionInterface
kwiberg2bbff992016-03-16 11:03:04 -07001071 // is returned and the MediaStream is stored in
deadbeefab9b2d12015-10-14 11:33:11 -07001072 // |reference_collection_|
kwibergd1fe2812016-04-27 06:47:29 -07001073 std::unique_ptr<SessionDescriptionInterface>
kwiberg2bbff992016-03-16 11:03:04 -07001074 CreateSessionDescriptionAndReference(size_t number_of_audio_tracks,
1075 size_t number_of_video_tracks) {
1076 EXPECT_LE(number_of_audio_tracks, 2u);
1077 EXPECT_LE(number_of_video_tracks, 2u);
deadbeefab9b2d12015-10-14 11:33:11 -07001078
1079 reference_collection_ = StreamCollection::Create();
1080 std::string sdp_ms1 = std::string(kSdpStringInit);
1081
1082 std::string mediastream_label = kStreams[0];
1083
1084 rtc::scoped_refptr<webrtc::MediaStreamInterface> stream(
1085 webrtc::MediaStream::Create(mediastream_label));
1086 reference_collection_->AddStream(stream);
1087
1088 if (number_of_audio_tracks > 0) {
1089 sdp_ms1 += std::string(kSdpStringAudio);
1090 sdp_ms1 += std::string(kSdpStringMs1Audio0);
1091 AddAudioTrack(kAudioTracks[0], stream);
1092 }
1093 if (number_of_audio_tracks > 1) {
1094 sdp_ms1 += kSdpStringMs1Audio1;
1095 AddAudioTrack(kAudioTracks[1], stream);
1096 }
1097
1098 if (number_of_video_tracks > 0) {
1099 sdp_ms1 += std::string(kSdpStringVideo);
1100 sdp_ms1 += std::string(kSdpStringMs1Video0);
1101 AddVideoTrack(kVideoTracks[0], stream);
1102 }
1103 if (number_of_video_tracks > 1) {
1104 sdp_ms1 += kSdpStringMs1Video1;
1105 AddVideoTrack(kVideoTracks[1], stream);
1106 }
1107
kwibergd1fe2812016-04-27 06:47:29 -07001108 return std::unique_ptr<SessionDescriptionInterface>(
kwiberg2bbff992016-03-16 11:03:04 -07001109 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer,
1110 sdp_ms1, nullptr));
deadbeefab9b2d12015-10-14 11:33:11 -07001111 }
1112
1113 void AddAudioTrack(const std::string& track_id,
1114 MediaStreamInterface* stream) {
1115 rtc::scoped_refptr<webrtc::AudioTrackInterface> audio_track(
1116 webrtc::AudioTrack::Create(track_id, nullptr));
1117 ASSERT_TRUE(stream->AddTrack(audio_track));
1118 }
1119
1120 void AddVideoTrack(const std::string& track_id,
1121 MediaStreamInterface* stream) {
1122 rtc::scoped_refptr<webrtc::VideoTrackInterface> video_track(
nisseaf510af2016-03-21 08:20:42 -07001123 webrtc::VideoTrack::Create(track_id,
1124 webrtc::FakeVideoTrackSource::Create()));
deadbeefab9b2d12015-10-14 11:33:11 -07001125 ASSERT_TRUE(stream->AddTrack(video_track));
1126 }
1127
kwibergfd8be342016-05-14 19:44:11 -07001128 std::unique_ptr<SessionDescriptionInterface> CreateOfferWithOneAudioStream() {
deadbeef293e9262017-01-11 12:28:30 -08001129 CreatePeerConnectionWithoutDtls();
zhihuang8f65cdf2016-05-06 18:40:30 -07001130 AddVoiceStream(kStreamLabel1);
kwibergfd8be342016-05-14 19:44:11 -07001131 std::unique_ptr<SessionDescriptionInterface> offer;
zhihuang8f65cdf2016-05-06 18:40:30 -07001132 EXPECT_TRUE(DoCreateOffer(&offer, nullptr));
1133 return offer;
1134 }
1135
kwibergfd8be342016-05-14 19:44:11 -07001136 std::unique_ptr<SessionDescriptionInterface>
zhihuang8f65cdf2016-05-06 18:40:30 -07001137 CreateAnswerWithOneAudioStream() {
kwibergfd8be342016-05-14 19:44:11 -07001138 std::unique_ptr<SessionDescriptionInterface> offer =
zhihuang8f65cdf2016-05-06 18:40:30 -07001139 CreateOfferWithOneAudioStream();
1140 EXPECT_TRUE(DoSetRemoteDescription(offer.release()));
kwibergfd8be342016-05-14 19:44:11 -07001141 std::unique_ptr<SessionDescriptionInterface> answer;
zhihuang8f65cdf2016-05-06 18:40:30 -07001142 EXPECT_TRUE(DoCreateAnswer(&answer, nullptr));
1143 return answer;
1144 }
1145
1146 const std::string& GetFirstAudioStreamCname(
1147 const SessionDescriptionInterface* desc) {
1148 const cricket::ContentInfo* audio_content =
1149 cricket::GetFirstAudioContent(desc->description());
1150 const cricket::AudioContentDescription* audio_desc =
1151 static_cast<const cricket::AudioContentDescription*>(
1152 audio_content->description);
1153 return audio_desc->streams()[0].cname;
1154 }
1155
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -08001156 cricket::FakePortAllocator* port_allocator_ = nullptr;
deadbeef8662f942017-01-20 21:20:51 -08001157 FakeRTCCertificateGenerator* fake_certificate_generator_ = nullptr;
zhihuang9763d562016-08-05 11:14:50 -07001158 rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> pc_factory_;
1159 rtc::scoped_refptr<PeerConnectionFactoryForTest> pc_factory_for_test_;
1160 rtc::scoped_refptr<PeerConnectionInterface> pc_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001161 MockPeerConnectionObserver observer_;
deadbeefab9b2d12015-10-14 11:33:11 -07001162 rtc::scoped_refptr<StreamCollection> reference_collection_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001163};
1164
zhihuang29ff8442016-07-27 11:07:25 -07001165// Test that no callbacks on the PeerConnectionObserver are called after the
1166// PeerConnection is closed.
1167TEST_F(PeerConnectionInterfaceTest, CloseAndTestCallbackFunctions) {
zhihuang9763d562016-08-05 11:14:50 -07001168 rtc::scoped_refptr<PeerConnectionInterface> pc(
zhihuang29ff8442016-07-27 11:07:25 -07001169 pc_factory_for_test_->CreatePeerConnection(
1170 PeerConnectionInterface::RTCConfiguration(), nullptr, nullptr,
1171 nullptr, &observer_));
1172 observer_.SetPeerConnectionInterface(pc.get());
1173 pc->Close();
1174
1175 // No callbacks is expected to be called.
zhihuang81c3a032016-11-17 12:06:24 -08001176 observer_.callback_triggered_ = false;
zhihuang29ff8442016-07-27 11:07:25 -07001177 std::vector<cricket::Candidate> candidates;
1178 pc_factory_for_test_->transport_controller->SignalGatheringState(
1179 cricket::IceGatheringState{});
1180 pc_factory_for_test_->transport_controller->SignalCandidatesGathered(
1181 "", candidates);
1182 pc_factory_for_test_->transport_controller->SignalConnectionState(
1183 cricket::IceConnectionState{});
1184 pc_factory_for_test_->transport_controller->SignalCandidatesRemoved(
1185 candidates);
1186 pc_factory_for_test_->transport_controller->SignalReceiving(false);
zhihuang81c3a032016-11-17 12:06:24 -08001187 EXPECT_FALSE(observer_.callback_triggered_);
zhihuang29ff8442016-07-27 11:07:25 -07001188}
1189
zhihuang8f65cdf2016-05-06 18:40:30 -07001190// Generate different CNAMEs when PeerConnections are created.
1191// The CNAMEs are expected to be generated randomly. It is possible
1192// that the test fails, though the possibility is very low.
1193TEST_F(PeerConnectionInterfaceTest, CnameGenerationInOffer) {
kwibergfd8be342016-05-14 19:44:11 -07001194 std::unique_ptr<SessionDescriptionInterface> offer1 =
zhihuang8f65cdf2016-05-06 18:40:30 -07001195 CreateOfferWithOneAudioStream();
kwibergfd8be342016-05-14 19:44:11 -07001196 std::unique_ptr<SessionDescriptionInterface> offer2 =
zhihuang8f65cdf2016-05-06 18:40:30 -07001197 CreateOfferWithOneAudioStream();
1198 EXPECT_NE(GetFirstAudioStreamCname(offer1.get()),
1199 GetFirstAudioStreamCname(offer2.get()));
1200}
1201
1202TEST_F(PeerConnectionInterfaceTest, CnameGenerationInAnswer) {
kwibergfd8be342016-05-14 19:44:11 -07001203 std::unique_ptr<SessionDescriptionInterface> answer1 =
zhihuang8f65cdf2016-05-06 18:40:30 -07001204 CreateAnswerWithOneAudioStream();
kwibergfd8be342016-05-14 19:44:11 -07001205 std::unique_ptr<SessionDescriptionInterface> answer2 =
zhihuang8f65cdf2016-05-06 18:40:30 -07001206 CreateAnswerWithOneAudioStream();
1207 EXPECT_NE(GetFirstAudioStreamCname(answer1.get()),
1208 GetFirstAudioStreamCname(answer2.get()));
1209}
1210
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001211TEST_F(PeerConnectionInterfaceTest,
1212 CreatePeerConnectionWithDifferentConfigurations) {
1213 CreatePeerConnectionWithDifferentConfigurations();
1214}
1215
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001216TEST_F(PeerConnectionInterfaceTest,
1217 CreatePeerConnectionWithDifferentIceTransportsTypes) {
1218 CreatePeerConnectionWithIceTransportsType(PeerConnectionInterface::kNone);
1219 EXPECT_EQ(cricket::CF_NONE, port_allocator_->candidate_filter());
1220 CreatePeerConnectionWithIceTransportsType(PeerConnectionInterface::kRelay);
1221 EXPECT_EQ(cricket::CF_RELAY, port_allocator_->candidate_filter());
1222 CreatePeerConnectionWithIceTransportsType(PeerConnectionInterface::kNoHost);
1223 EXPECT_EQ(cricket::CF_ALL & ~cricket::CF_HOST,
1224 port_allocator_->candidate_filter());
1225 CreatePeerConnectionWithIceTransportsType(PeerConnectionInterface::kAll);
1226 EXPECT_EQ(cricket::CF_ALL, port_allocator_->candidate_filter());
1227}
1228
1229// Test that when a PeerConnection is created with a nonzero candidate pool
1230// size, the pooled PortAllocatorSession is created with all the attributes
1231// in the RTCConfiguration.
1232TEST_F(PeerConnectionInterfaceTest, CreatePeerConnectionWithPooledCandidates) {
1233 PeerConnectionInterface::RTCConfiguration config;
1234 PeerConnectionInterface::IceServer server;
1235 server.uri = kStunAddressOnly;
1236 config.servers.push_back(server);
1237 config.type = PeerConnectionInterface::kRelay;
1238 config.disable_ipv6 = true;
1239 config.tcp_candidate_policy =
1240 PeerConnectionInterface::kTcpCandidatePolicyDisabled;
honghaiz60347052016-05-31 18:29:12 -07001241 config.candidate_network_policy =
1242 PeerConnectionInterface::kCandidateNetworkPolicyLowCost;
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001243 config.ice_candidate_pool_size = 1;
1244 CreatePeerConnection(config, nullptr);
1245
1246 const cricket::FakePortAllocatorSession* session =
1247 static_cast<const cricket::FakePortAllocatorSession*>(
1248 port_allocator_->GetPooledSession());
1249 ASSERT_NE(nullptr, session);
1250 EXPECT_EQ(1UL, session->stun_servers().size());
1251 EXPECT_EQ(0U, session->flags() & cricket::PORTALLOCATOR_ENABLE_IPV6);
1252 EXPECT_LT(0U, session->flags() & cricket::PORTALLOCATOR_DISABLE_TCP);
honghaiz60347052016-05-31 18:29:12 -07001253 EXPECT_LT(0U,
1254 session->flags() & cricket::PORTALLOCATOR_DISABLE_COSTLY_NETWORKS);
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001255}
1256
Taylor Brandstetterf8e65772016-06-27 17:20:15 -07001257// Test that the PeerConnection initializes the port allocator passed into it,
1258// and on the correct thread.
1259TEST_F(PeerConnectionInterfaceTest,
1260 CreatePeerConnectionInitializesPortAllocator) {
1261 rtc::Thread network_thread;
1262 network_thread.Start();
1263 rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> pc_factory(
1264 webrtc::CreatePeerConnectionFactory(
1265 &network_thread, rtc::Thread::Current(), rtc::Thread::Current(),
1266 nullptr, nullptr, nullptr));
1267 std::unique_ptr<cricket::FakePortAllocator> port_allocator(
1268 new cricket::FakePortAllocator(&network_thread, nullptr));
1269 cricket::FakePortAllocator* raw_port_allocator = port_allocator.get();
1270 PeerConnectionInterface::RTCConfiguration config;
1271 rtc::scoped_refptr<PeerConnectionInterface> pc(
1272 pc_factory->CreatePeerConnection(
1273 config, nullptr, std::move(port_allocator), nullptr, &observer_));
1274 // FakePortAllocator RTC_CHECKs that it's initialized on the right thread,
1275 // so all we have to do here is check that it's initialized.
1276 EXPECT_TRUE(raw_port_allocator->initialized());
1277}
1278
deadbeef46c73892016-11-16 19:42:04 -08001279// Check that GetConfiguration returns the configuration the PeerConnection was
1280// constructed with, before SetConfiguration is called.
1281TEST_F(PeerConnectionInterfaceTest, GetConfigurationAfterCreatePeerConnection) {
1282 PeerConnectionInterface::RTCConfiguration config;
1283 config.type = PeerConnectionInterface::kRelay;
1284 CreatePeerConnection(config, nullptr);
1285
1286 PeerConnectionInterface::RTCConfiguration returned_config =
1287 pc_->GetConfiguration();
1288 EXPECT_EQ(PeerConnectionInterface::kRelay, returned_config.type);
1289}
1290
1291// Check that GetConfiguration returns the last configuration passed into
1292// SetConfiguration.
1293TEST_F(PeerConnectionInterfaceTest, GetConfigurationAfterSetConfiguration) {
1294 CreatePeerConnection();
1295
1296 PeerConnectionInterface::RTCConfiguration config;
1297 config.type = PeerConnectionInterface::kRelay;
1298 EXPECT_TRUE(pc_->SetConfiguration(config));
1299
1300 PeerConnectionInterface::RTCConfiguration returned_config =
1301 pc_->GetConfiguration();
1302 EXPECT_EQ(PeerConnectionInterface::kRelay, returned_config.type);
1303}
1304
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001305TEST_F(PeerConnectionInterfaceTest, AddStreams) {
deadbeef293e9262017-01-11 12:28:30 -08001306 CreatePeerConnectionWithoutDtls();
deadbeefab9b2d12015-10-14 11:33:11 -07001307 AddVideoStream(kStreamLabel1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001308 AddVoiceStream(kStreamLabel2);
1309 ASSERT_EQ(2u, pc_->local_streams()->count());
1310
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001311 // Test we can add multiple local streams to one peerconnection.
zhihuang9763d562016-08-05 11:14:50 -07001312 rtc::scoped_refptr<MediaStreamInterface> stream(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001313 pc_factory_->CreateLocalMediaStream(kStreamLabel3));
zhihuang9763d562016-08-05 11:14:50 -07001314 rtc::scoped_refptr<AudioTrackInterface> audio_track(
1315 pc_factory_->CreateAudioTrack(kStreamLabel3,
1316 static_cast<AudioSourceInterface*>(NULL)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001317 stream->AddTrack(audio_track.get());
perkj@webrtc.orgc2dd5ee2014-11-04 11:31:29 +00001318 EXPECT_TRUE(pc_->AddStream(stream));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001319 EXPECT_EQ(3u, pc_->local_streams()->count());
1320
1321 // Remove the third stream.
1322 pc_->RemoveStream(pc_->local_streams()->at(2));
1323 EXPECT_EQ(2u, pc_->local_streams()->count());
1324
1325 // Remove the second stream.
1326 pc_->RemoveStream(pc_->local_streams()->at(1));
1327 EXPECT_EQ(1u, pc_->local_streams()->count());
1328
1329 // Remove the first stream.
1330 pc_->RemoveStream(pc_->local_streams()->at(0));
1331 EXPECT_EQ(0u, pc_->local_streams()->count());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001332}
1333
deadbeefab9b2d12015-10-14 11:33:11 -07001334// Test that the created offer includes streams we added.
1335TEST_F(PeerConnectionInterfaceTest, AddedStreamsPresentInOffer) {
deadbeef293e9262017-01-11 12:28:30 -08001336 CreatePeerConnectionWithoutDtls();
deadbeefab9b2d12015-10-14 11:33:11 -07001337 AddAudioVideoStream(kStreamLabel1, "audio_track", "video_track");
kwibergd1fe2812016-04-27 06:47:29 -07001338 std::unique_ptr<SessionDescriptionInterface> offer;
kwiberg2bbff992016-03-16 11:03:04 -07001339 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
deadbeefab9b2d12015-10-14 11:33:11 -07001340
1341 const cricket::ContentInfo* audio_content =
1342 cricket::GetFirstAudioContent(offer->description());
1343 const cricket::AudioContentDescription* audio_desc =
1344 static_cast<const cricket::AudioContentDescription*>(
1345 audio_content->description);
1346 EXPECT_TRUE(
1347 ContainsTrack(audio_desc->streams(), kStreamLabel1, "audio_track"));
1348
1349 const cricket::ContentInfo* video_content =
1350 cricket::GetFirstVideoContent(offer->description());
1351 const cricket::VideoContentDescription* video_desc =
1352 static_cast<const cricket::VideoContentDescription*>(
1353 video_content->description);
1354 EXPECT_TRUE(
1355 ContainsTrack(video_desc->streams(), kStreamLabel1, "video_track"));
1356
1357 // Add another stream and ensure the offer includes both the old and new
1358 // streams.
1359 AddAudioVideoStream(kStreamLabel2, "audio_track2", "video_track2");
kwiberg2bbff992016-03-16 11:03:04 -07001360 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
deadbeefab9b2d12015-10-14 11:33:11 -07001361
1362 audio_content = cricket::GetFirstAudioContent(offer->description());
1363 audio_desc = static_cast<const cricket::AudioContentDescription*>(
1364 audio_content->description);
1365 EXPECT_TRUE(
1366 ContainsTrack(audio_desc->streams(), kStreamLabel1, "audio_track"));
1367 EXPECT_TRUE(
1368 ContainsTrack(audio_desc->streams(), kStreamLabel2, "audio_track2"));
1369
1370 video_content = cricket::GetFirstVideoContent(offer->description());
1371 video_desc = static_cast<const cricket::VideoContentDescription*>(
1372 video_content->description);
1373 EXPECT_TRUE(
1374 ContainsTrack(video_desc->streams(), kStreamLabel1, "video_track"));
1375 EXPECT_TRUE(
1376 ContainsTrack(video_desc->streams(), kStreamLabel2, "video_track2"));
1377}
1378
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001379TEST_F(PeerConnectionInterfaceTest, RemoveStream) {
deadbeef293e9262017-01-11 12:28:30 -08001380 CreatePeerConnectionWithoutDtls();
deadbeefab9b2d12015-10-14 11:33:11 -07001381 AddVideoStream(kStreamLabel1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001382 ASSERT_EQ(1u, pc_->local_streams()->count());
1383 pc_->RemoveStream(pc_->local_streams()->at(0));
1384 EXPECT_EQ(0u, pc_->local_streams()->count());
1385}
1386
deadbeefe1f9d832016-01-14 15:35:42 -08001387// Test for AddTrack and RemoveTrack methods.
1388// Tests that the created offer includes tracks we added,
1389// and that the RtpSenders are created correctly.
1390// Also tests that RemoveTrack removes the tracks from subsequent offers.
1391TEST_F(PeerConnectionInterfaceTest, AddTrackRemoveTrack) {
deadbeef293e9262017-01-11 12:28:30 -08001392 CreatePeerConnectionWithoutDtls();
deadbeefe1f9d832016-01-14 15:35:42 -08001393 // Create a dummy stream, so tracks share a stream label.
zhihuang9763d562016-08-05 11:14:50 -07001394 rtc::scoped_refptr<MediaStreamInterface> stream(
deadbeefe1f9d832016-01-14 15:35:42 -08001395 pc_factory_->CreateLocalMediaStream(kStreamLabel1));
1396 std::vector<MediaStreamInterface*> stream_list;
1397 stream_list.push_back(stream.get());
zhihuang9763d562016-08-05 11:14:50 -07001398 rtc::scoped_refptr<AudioTrackInterface> audio_track(
deadbeefe1f9d832016-01-14 15:35:42 -08001399 pc_factory_->CreateAudioTrack("audio_track", nullptr));
zhihuang9763d562016-08-05 11:14:50 -07001400 rtc::scoped_refptr<VideoTrackInterface> video_track(
1401 pc_factory_->CreateVideoTrack(
1402 "video_track",
1403 pc_factory_->CreateVideoSource(new cricket::FakeVideoCapturer())));
deadbeefe1f9d832016-01-14 15:35:42 -08001404 auto audio_sender = pc_->AddTrack(audio_track, stream_list);
1405 auto video_sender = pc_->AddTrack(video_track, stream_list);
deadbeefa601f5c2016-06-06 14:27:39 -07001406 EXPECT_EQ(1UL, audio_sender->stream_ids().size());
1407 EXPECT_EQ(kStreamLabel1, audio_sender->stream_ids()[0]);
deadbeefe1f9d832016-01-14 15:35:42 -08001408 EXPECT_EQ("audio_track", audio_sender->id());
1409 EXPECT_EQ(audio_track, audio_sender->track());
deadbeefa601f5c2016-06-06 14:27:39 -07001410 EXPECT_EQ(1UL, video_sender->stream_ids().size());
1411 EXPECT_EQ(kStreamLabel1, video_sender->stream_ids()[0]);
deadbeefe1f9d832016-01-14 15:35:42 -08001412 EXPECT_EQ("video_track", video_sender->id());
1413 EXPECT_EQ(video_track, video_sender->track());
1414
1415 // Now create an offer and check for the senders.
kwibergd1fe2812016-04-27 06:47:29 -07001416 std::unique_ptr<SessionDescriptionInterface> offer;
kwiberg2bbff992016-03-16 11:03:04 -07001417 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
deadbeefe1f9d832016-01-14 15:35:42 -08001418
1419 const cricket::ContentInfo* audio_content =
1420 cricket::GetFirstAudioContent(offer->description());
1421 const cricket::AudioContentDescription* audio_desc =
1422 static_cast<const cricket::AudioContentDescription*>(
1423 audio_content->description);
1424 EXPECT_TRUE(
1425 ContainsTrack(audio_desc->streams(), kStreamLabel1, "audio_track"));
1426
1427 const cricket::ContentInfo* video_content =
1428 cricket::GetFirstVideoContent(offer->description());
1429 const cricket::VideoContentDescription* video_desc =
1430 static_cast<const cricket::VideoContentDescription*>(
1431 video_content->description);
1432 EXPECT_TRUE(
1433 ContainsTrack(video_desc->streams(), kStreamLabel1, "video_track"));
1434
1435 EXPECT_TRUE(DoSetLocalDescription(offer.release()));
1436
1437 // Now try removing the tracks.
1438 EXPECT_TRUE(pc_->RemoveTrack(audio_sender));
1439 EXPECT_TRUE(pc_->RemoveTrack(video_sender));
1440
1441 // Create a new offer and ensure it doesn't contain the removed senders.
kwiberg2bbff992016-03-16 11:03:04 -07001442 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
deadbeefe1f9d832016-01-14 15:35:42 -08001443
1444 audio_content = cricket::GetFirstAudioContent(offer->description());
1445 audio_desc = static_cast<const cricket::AudioContentDescription*>(
1446 audio_content->description);
1447 EXPECT_FALSE(
1448 ContainsTrack(audio_desc->streams(), kStreamLabel1, "audio_track"));
1449
1450 video_content = cricket::GetFirstVideoContent(offer->description());
1451 video_desc = static_cast<const cricket::VideoContentDescription*>(
1452 video_content->description);
1453 EXPECT_FALSE(
1454 ContainsTrack(video_desc->streams(), kStreamLabel1, "video_track"));
1455
1456 EXPECT_TRUE(DoSetLocalDescription(offer.release()));
1457
1458 // Calling RemoveTrack on a sender no longer attached to a PeerConnection
1459 // should return false.
1460 EXPECT_FALSE(pc_->RemoveTrack(audio_sender));
1461 EXPECT_FALSE(pc_->RemoveTrack(video_sender));
1462}
1463
1464// Test creating senders without a stream specified,
1465// expecting a random stream ID to be generated.
1466TEST_F(PeerConnectionInterfaceTest, AddTrackWithoutStream) {
deadbeef293e9262017-01-11 12:28:30 -08001467 CreatePeerConnectionWithoutDtls();
deadbeefe1f9d832016-01-14 15:35:42 -08001468 // Create a dummy stream, so tracks share a stream label.
zhihuang9763d562016-08-05 11:14:50 -07001469 rtc::scoped_refptr<AudioTrackInterface> audio_track(
deadbeefe1f9d832016-01-14 15:35:42 -08001470 pc_factory_->CreateAudioTrack("audio_track", nullptr));
zhihuang9763d562016-08-05 11:14:50 -07001471 rtc::scoped_refptr<VideoTrackInterface> video_track(
1472 pc_factory_->CreateVideoTrack(
1473 "video_track",
1474 pc_factory_->CreateVideoSource(new cricket::FakeVideoCapturer())));
deadbeefe1f9d832016-01-14 15:35:42 -08001475 auto audio_sender =
1476 pc_->AddTrack(audio_track, std::vector<MediaStreamInterface*>());
1477 auto video_sender =
1478 pc_->AddTrack(video_track, std::vector<MediaStreamInterface*>());
1479 EXPECT_EQ("audio_track", audio_sender->id());
1480 EXPECT_EQ(audio_track, audio_sender->track());
1481 EXPECT_EQ("video_track", video_sender->id());
1482 EXPECT_EQ(video_track, video_sender->track());
1483 // If the ID is truly a random GUID, it should be infinitely unlikely they
1484 // will be the same.
deadbeefa601f5c2016-06-06 14:27:39 -07001485 EXPECT_NE(video_sender->stream_ids(), audio_sender->stream_ids());
deadbeefe1f9d832016-01-14 15:35:42 -08001486}
1487
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001488TEST_F(PeerConnectionInterfaceTest, CreateOfferReceiveAnswer) {
1489 InitiateCall();
1490 WaitAndVerifyOnAddStream(kStreamLabel1);
1491 VerifyRemoteRtpHeaderExtensions();
1492}
1493
1494TEST_F(PeerConnectionInterfaceTest, CreateOfferReceivePrAnswerAndAnswer) {
deadbeef293e9262017-01-11 12:28:30 -08001495 CreatePeerConnectionWithoutDtls();
deadbeefab9b2d12015-10-14 11:33:11 -07001496 AddVideoStream(kStreamLabel1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001497 CreateOfferAsLocalDescription();
1498 std::string offer;
1499 EXPECT_TRUE(pc_->local_description()->ToString(&offer));
1500 CreatePrAnswerAndAnswerAsRemoteDescription(offer);
1501 WaitAndVerifyOnAddStream(kStreamLabel1);
1502}
1503
1504TEST_F(PeerConnectionInterfaceTest, ReceiveOfferCreateAnswer) {
deadbeef293e9262017-01-11 12:28:30 -08001505 CreatePeerConnectionWithoutDtls();
deadbeefab9b2d12015-10-14 11:33:11 -07001506 AddVideoStream(kStreamLabel1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001507
1508 CreateOfferAsRemoteDescription();
1509 CreateAnswerAsLocalDescription();
1510
1511 WaitAndVerifyOnAddStream(kStreamLabel1);
1512}
1513
1514TEST_F(PeerConnectionInterfaceTest, ReceiveOfferCreatePrAnswerAndAnswer) {
deadbeef293e9262017-01-11 12:28:30 -08001515 CreatePeerConnectionWithoutDtls();
deadbeefab9b2d12015-10-14 11:33:11 -07001516 AddVideoStream(kStreamLabel1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001517
1518 CreateOfferAsRemoteDescription();
1519 CreatePrAnswerAsLocalDescription();
1520 CreateAnswerAsLocalDescription();
1521
1522 WaitAndVerifyOnAddStream(kStreamLabel1);
1523}
1524
1525TEST_F(PeerConnectionInterfaceTest, Renegotiate) {
1526 InitiateCall();
1527 ASSERT_EQ(1u, pc_->remote_streams()->count());
1528 pc_->RemoveStream(pc_->local_streams()->at(0));
1529 CreateOfferReceiveAnswer();
1530 EXPECT_EQ(0u, pc_->remote_streams()->count());
deadbeefab9b2d12015-10-14 11:33:11 -07001531 AddVideoStream(kStreamLabel1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001532 CreateOfferReceiveAnswer();
1533}
1534
1535// Tests that after negotiating an audio only call, the respondent can perform a
1536// renegotiation that removes the audio stream.
1537TEST_F(PeerConnectionInterfaceTest, RenegotiateAudioOnly) {
deadbeef293e9262017-01-11 12:28:30 -08001538 CreatePeerConnectionWithoutDtls();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001539 AddVoiceStream(kStreamLabel1);
1540 CreateOfferAsRemoteDescription();
1541 CreateAnswerAsLocalDescription();
1542
1543 ASSERT_EQ(1u, pc_->remote_streams()->count());
1544 pc_->RemoveStream(pc_->local_streams()->at(0));
1545 CreateOfferReceiveAnswer();
1546 EXPECT_EQ(0u, pc_->remote_streams()->count());
1547}
1548
1549// Test that candidates are generated and that we can parse our own candidates.
1550TEST_F(PeerConnectionInterfaceTest, IceCandidates) {
deadbeef293e9262017-01-11 12:28:30 -08001551 CreatePeerConnectionWithoutDtls();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001552
1553 EXPECT_FALSE(pc_->AddIceCandidate(observer_.last_candidate_.get()));
1554 // SetRemoteDescription takes ownership of offer.
kwibergd1fe2812016-04-27 06:47:29 -07001555 std::unique_ptr<SessionDescriptionInterface> offer;
deadbeefab9b2d12015-10-14 11:33:11 -07001556 AddVideoStream(kStreamLabel1);
deadbeefc80741f2015-10-22 13:14:45 -07001557 EXPECT_TRUE(DoCreateOffer(&offer, nullptr));
kwiberg2bbff992016-03-16 11:03:04 -07001558 EXPECT_TRUE(DoSetRemoteDescription(offer.release()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001559
1560 // SetLocalDescription takes ownership of answer.
kwibergd1fe2812016-04-27 06:47:29 -07001561 std::unique_ptr<SessionDescriptionInterface> answer;
deadbeefc80741f2015-10-22 13:14:45 -07001562 EXPECT_TRUE(DoCreateAnswer(&answer, nullptr));
kwiberg2bbff992016-03-16 11:03:04 -07001563 EXPECT_TRUE(DoSetLocalDescription(answer.release()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001564
1565 EXPECT_TRUE_WAIT(observer_.last_candidate_.get() != NULL, kTimeout);
1566 EXPECT_TRUE_WAIT(observer_.ice_complete_, kTimeout);
1567
1568 EXPECT_TRUE(pc_->AddIceCandidate(observer_.last_candidate_.get()));
1569}
1570
deadbeefab9b2d12015-10-14 11:33:11 -07001571// Test that CreateOffer and CreateAnswer will fail if the track labels are
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001572// not unique.
1573TEST_F(PeerConnectionInterfaceTest, CreateOfferAnswerWithInvalidStream) {
deadbeef293e9262017-01-11 12:28:30 -08001574 CreatePeerConnectionWithoutDtls();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001575 // Create a regular offer for the CreateAnswer test later.
kwibergd1fe2812016-04-27 06:47:29 -07001576 std::unique_ptr<SessionDescriptionInterface> offer;
deadbeefc80741f2015-10-22 13:14:45 -07001577 EXPECT_TRUE(DoCreateOffer(&offer, nullptr));
kwiberg2bbff992016-03-16 11:03:04 -07001578 EXPECT_TRUE(offer);
1579 offer.reset();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001580
1581 // Create a local stream with audio&video tracks having same label.
1582 AddAudioVideoStream(kStreamLabel1, "track_label", "track_label");
1583
1584 // Test CreateOffer
deadbeefc80741f2015-10-22 13:14:45 -07001585 EXPECT_FALSE(DoCreateOffer(&offer, nullptr));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001586
1587 // Test CreateAnswer
kwibergd1fe2812016-04-27 06:47:29 -07001588 std::unique_ptr<SessionDescriptionInterface> answer;
deadbeefc80741f2015-10-22 13:14:45 -07001589 EXPECT_FALSE(DoCreateAnswer(&answer, nullptr));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001590}
1591
1592// Test that we will get different SSRCs for each tracks in the offer and answer
1593// we created.
1594TEST_F(PeerConnectionInterfaceTest, SsrcInOfferAnswer) {
deadbeef293e9262017-01-11 12:28:30 -08001595 CreatePeerConnectionWithoutDtls();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001596 // Create a local stream with audio&video tracks having different labels.
1597 AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label");
1598
1599 // Test CreateOffer
kwibergd1fe2812016-04-27 06:47:29 -07001600 std::unique_ptr<SessionDescriptionInterface> offer;
kwiberg2bbff992016-03-16 11:03:04 -07001601 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001602 int audio_ssrc = 0;
1603 int video_ssrc = 0;
1604 EXPECT_TRUE(GetFirstSsrc(GetFirstAudioContent(offer->description()),
1605 &audio_ssrc));
1606 EXPECT_TRUE(GetFirstSsrc(GetFirstVideoContent(offer->description()),
1607 &video_ssrc));
1608 EXPECT_NE(audio_ssrc, video_ssrc);
1609
1610 // Test CreateAnswer
1611 EXPECT_TRUE(DoSetRemoteDescription(offer.release()));
kwibergd1fe2812016-04-27 06:47:29 -07001612 std::unique_ptr<SessionDescriptionInterface> answer;
kwiberg2bbff992016-03-16 11:03:04 -07001613 ASSERT_TRUE(DoCreateAnswer(&answer, nullptr));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001614 audio_ssrc = 0;
1615 video_ssrc = 0;
1616 EXPECT_TRUE(GetFirstSsrc(GetFirstAudioContent(answer->description()),
1617 &audio_ssrc));
1618 EXPECT_TRUE(GetFirstSsrc(GetFirstVideoContent(answer->description()),
1619 &video_ssrc));
1620 EXPECT_NE(audio_ssrc, video_ssrc);
1621}
1622
deadbeefeb459812015-12-15 19:24:43 -08001623// Test that it's possible to call AddTrack on a MediaStream after adding
1624// the stream to a PeerConnection.
1625// TODO(deadbeef): Remove this test once this behavior is no longer supported.
1626TEST_F(PeerConnectionInterfaceTest, AddTrackAfterAddStream) {
deadbeef293e9262017-01-11 12:28:30 -08001627 CreatePeerConnectionWithoutDtls();
deadbeefeb459812015-12-15 19:24:43 -08001628 // Create audio stream and add to PeerConnection.
1629 AddVoiceStream(kStreamLabel1);
1630 MediaStreamInterface* stream = pc_->local_streams()->at(0);
1631
1632 // Add video track to the audio-only stream.
zhihuang9763d562016-08-05 11:14:50 -07001633 rtc::scoped_refptr<VideoTrackInterface> video_track(
1634 pc_factory_->CreateVideoTrack(
1635 "video_label",
1636 pc_factory_->CreateVideoSource(new cricket::FakeVideoCapturer())));
deadbeefeb459812015-12-15 19:24:43 -08001637 stream->AddTrack(video_track.get());
1638
kwibergd1fe2812016-04-27 06:47:29 -07001639 std::unique_ptr<SessionDescriptionInterface> offer;
kwiberg2bbff992016-03-16 11:03:04 -07001640 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
deadbeefeb459812015-12-15 19:24:43 -08001641
1642 const cricket::MediaContentDescription* video_desc =
1643 cricket::GetFirstVideoContentDescription(offer->description());
1644 EXPECT_TRUE(video_desc != nullptr);
1645}
1646
1647// Test that it's possible to call RemoveTrack on a MediaStream after adding
1648// the stream to a PeerConnection.
1649// TODO(deadbeef): Remove this test once this behavior is no longer supported.
1650TEST_F(PeerConnectionInterfaceTest, RemoveTrackAfterAddStream) {
deadbeef293e9262017-01-11 12:28:30 -08001651 CreatePeerConnectionWithoutDtls();
deadbeefeb459812015-12-15 19:24:43 -08001652 // Create audio/video stream and add to PeerConnection.
1653 AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label");
1654 MediaStreamInterface* stream = pc_->local_streams()->at(0);
1655
1656 // Remove the video track.
1657 stream->RemoveTrack(stream->GetVideoTracks()[0]);
1658
kwibergd1fe2812016-04-27 06:47:29 -07001659 std::unique_ptr<SessionDescriptionInterface> offer;
kwiberg2bbff992016-03-16 11:03:04 -07001660 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
deadbeefeb459812015-12-15 19:24:43 -08001661
1662 const cricket::MediaContentDescription* video_desc =
1663 cricket::GetFirstVideoContentDescription(offer->description());
1664 EXPECT_TRUE(video_desc == nullptr);
1665}
1666
deadbeefbd7d8f72015-12-18 16:58:44 -08001667// Test creating a sender with a stream ID, and ensure the ID is populated
1668// in the offer.
1669TEST_F(PeerConnectionInterfaceTest, CreateSenderWithStream) {
deadbeef293e9262017-01-11 12:28:30 -08001670 CreatePeerConnectionWithoutDtls();
deadbeefbd7d8f72015-12-18 16:58:44 -08001671 pc_->CreateSender("video", kStreamLabel1);
1672
kwibergd1fe2812016-04-27 06:47:29 -07001673 std::unique_ptr<SessionDescriptionInterface> offer;
kwiberg2bbff992016-03-16 11:03:04 -07001674 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
deadbeefbd7d8f72015-12-18 16:58:44 -08001675
1676 const cricket::MediaContentDescription* video_desc =
1677 cricket::GetFirstVideoContentDescription(offer->description());
1678 ASSERT_TRUE(video_desc != nullptr);
1679 ASSERT_EQ(1u, video_desc->streams().size());
1680 EXPECT_EQ(kStreamLabel1, video_desc->streams()[0].sync_label);
1681}
1682
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001683// Test that we can specify a certain track that we want statistics about.
1684TEST_F(PeerConnectionInterfaceTest, GetStatsForSpecificTrack) {
1685 InitiateCall();
1686 ASSERT_LT(0u, pc_->remote_streams()->count());
1687 ASSERT_LT(0u, pc_->remote_streams()->at(0)->GetAudioTracks().size());
zhihuang9763d562016-08-05 11:14:50 -07001688 rtc::scoped_refptr<MediaStreamTrackInterface> remote_audio =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001689 pc_->remote_streams()->at(0)->GetAudioTracks()[0];
1690 EXPECT_TRUE(DoGetStats(remote_audio));
1691
1692 // Remove the stream. Since we are sending to our selves the local
1693 // and the remote stream is the same.
1694 pc_->RemoveStream(pc_->local_streams()->at(0));
1695 // Do a re-negotiation.
1696 CreateOfferReceiveAnswer();
1697
1698 ASSERT_EQ(0u, pc_->remote_streams()->count());
1699
1700 // Test that we still can get statistics for the old track. Even if it is not
1701 // sent any longer.
1702 EXPECT_TRUE(DoGetStats(remote_audio));
1703}
1704
1705// Test that we can get stats on a video track.
1706TEST_F(PeerConnectionInterfaceTest, GetStatsForVideoTrack) {
1707 InitiateCall();
1708 ASSERT_LT(0u, pc_->remote_streams()->count());
1709 ASSERT_LT(0u, pc_->remote_streams()->at(0)->GetVideoTracks().size());
zhihuang9763d562016-08-05 11:14:50 -07001710 rtc::scoped_refptr<MediaStreamTrackInterface> remote_video =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001711 pc_->remote_streams()->at(0)->GetVideoTracks()[0];
1712 EXPECT_TRUE(DoGetStats(remote_video));
1713}
1714
1715// Test that we don't get statistics for an invalid track.
zhihuange9e94c32016-11-04 11:38:15 -07001716TEST_F(PeerConnectionInterfaceTest, GetStatsForInvalidTrack) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001717 InitiateCall();
zhihuang9763d562016-08-05 11:14:50 -07001718 rtc::scoped_refptr<AudioTrackInterface> unknown_audio_track(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001719 pc_factory_->CreateAudioTrack("unknown track", NULL));
1720 EXPECT_FALSE(DoGetStats(unknown_audio_track));
1721}
1722
1723// This test setup two RTP data channels in loop back.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001724TEST_F(PeerConnectionInterfaceTest, TestDataChannel) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001725 FakeConstraints constraints;
1726 constraints.SetAllowRtpDataChannels();
1727 CreatePeerConnection(&constraints);
zhihuang9763d562016-08-05 11:14:50 -07001728 rtc::scoped_refptr<DataChannelInterface> data1 =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001729 pc_->CreateDataChannel("test1", NULL);
zhihuang9763d562016-08-05 11:14:50 -07001730 rtc::scoped_refptr<DataChannelInterface> data2 =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001731 pc_->CreateDataChannel("test2", NULL);
1732 ASSERT_TRUE(data1 != NULL);
kwibergd1fe2812016-04-27 06:47:29 -07001733 std::unique_ptr<MockDataChannelObserver> observer1(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001734 new MockDataChannelObserver(data1));
kwibergd1fe2812016-04-27 06:47:29 -07001735 std::unique_ptr<MockDataChannelObserver> observer2(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001736 new MockDataChannelObserver(data2));
1737
1738 EXPECT_EQ(DataChannelInterface::kConnecting, data1->state());
1739 EXPECT_EQ(DataChannelInterface::kConnecting, data2->state());
1740 std::string data_to_send1 = "testing testing";
1741 std::string data_to_send2 = "testing something else";
1742 EXPECT_FALSE(data1->Send(DataBuffer(data_to_send1)));
1743
1744 CreateOfferReceiveAnswer();
1745 EXPECT_TRUE_WAIT(observer1->IsOpen(), kTimeout);
1746 EXPECT_TRUE_WAIT(observer2->IsOpen(), kTimeout);
1747
1748 EXPECT_EQ(DataChannelInterface::kOpen, data1->state());
1749 EXPECT_EQ(DataChannelInterface::kOpen, data2->state());
1750 EXPECT_TRUE(data1->Send(DataBuffer(data_to_send1)));
1751 EXPECT_TRUE(data2->Send(DataBuffer(data_to_send2)));
1752
1753 EXPECT_EQ_WAIT(data_to_send1, observer1->last_message(), kTimeout);
1754 EXPECT_EQ_WAIT(data_to_send2, observer2->last_message(), kTimeout);
1755
1756 data1->Close();
1757 EXPECT_EQ(DataChannelInterface::kClosing, data1->state());
1758 CreateOfferReceiveAnswer();
1759 EXPECT_FALSE(observer1->IsOpen());
1760 EXPECT_EQ(DataChannelInterface::kClosed, data1->state());
1761 EXPECT_TRUE(observer2->IsOpen());
1762
1763 data_to_send2 = "testing something else again";
1764 EXPECT_TRUE(data2->Send(DataBuffer(data_to_send2)));
1765
1766 EXPECT_EQ_WAIT(data_to_send2, observer2->last_message(), kTimeout);
1767}
1768
1769// This test verifies that sendnig binary data over RTP data channels should
1770// fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001771TEST_F(PeerConnectionInterfaceTest, TestSendBinaryOnRtpDataChannel) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001772 FakeConstraints constraints;
1773 constraints.SetAllowRtpDataChannels();
1774 CreatePeerConnection(&constraints);
zhihuang9763d562016-08-05 11:14:50 -07001775 rtc::scoped_refptr<DataChannelInterface> data1 =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001776 pc_->CreateDataChannel("test1", NULL);
zhihuang9763d562016-08-05 11:14:50 -07001777 rtc::scoped_refptr<DataChannelInterface> data2 =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001778 pc_->CreateDataChannel("test2", NULL);
1779 ASSERT_TRUE(data1 != NULL);
kwibergd1fe2812016-04-27 06:47:29 -07001780 std::unique_ptr<MockDataChannelObserver> observer1(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001781 new MockDataChannelObserver(data1));
kwibergd1fe2812016-04-27 06:47:29 -07001782 std::unique_ptr<MockDataChannelObserver> observer2(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001783 new MockDataChannelObserver(data2));
1784
1785 EXPECT_EQ(DataChannelInterface::kConnecting, data1->state());
1786 EXPECT_EQ(DataChannelInterface::kConnecting, data2->state());
1787
1788 CreateOfferReceiveAnswer();
1789 EXPECT_TRUE_WAIT(observer1->IsOpen(), kTimeout);
1790 EXPECT_TRUE_WAIT(observer2->IsOpen(), kTimeout);
1791
1792 EXPECT_EQ(DataChannelInterface::kOpen, data1->state());
1793 EXPECT_EQ(DataChannelInterface::kOpen, data2->state());
1794
jbaucheec21bd2016-03-20 06:15:43 -07001795 rtc::CopyOnWriteBuffer buffer("test", 4);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001796 EXPECT_FALSE(data1->Send(DataBuffer(buffer, true)));
1797}
1798
1799// This test setup a RTP data channels in loop back and test that a channel is
1800// opened even if the remote end answer with a zero SSRC.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001801TEST_F(PeerConnectionInterfaceTest, TestSendOnlyDataChannel) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001802 FakeConstraints constraints;
1803 constraints.SetAllowRtpDataChannels();
1804 CreatePeerConnection(&constraints);
zhihuang9763d562016-08-05 11:14:50 -07001805 rtc::scoped_refptr<DataChannelInterface> data1 =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001806 pc_->CreateDataChannel("test1", NULL);
kwibergd1fe2812016-04-27 06:47:29 -07001807 std::unique_ptr<MockDataChannelObserver> observer1(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001808 new MockDataChannelObserver(data1));
1809
1810 CreateOfferReceiveAnswerWithoutSsrc();
1811
1812 EXPECT_TRUE_WAIT(observer1->IsOpen(), kTimeout);
1813
1814 data1->Close();
1815 EXPECT_EQ(DataChannelInterface::kClosing, data1->state());
1816 CreateOfferReceiveAnswerWithoutSsrc();
1817 EXPECT_EQ(DataChannelInterface::kClosed, data1->state());
1818 EXPECT_FALSE(observer1->IsOpen());
1819}
1820
1821// This test that if a data channel is added in an answer a receive only channel
1822// channel is created.
1823TEST_F(PeerConnectionInterfaceTest, TestReceiveOnlyDataChannel) {
1824 FakeConstraints constraints;
1825 constraints.SetAllowRtpDataChannels();
1826 CreatePeerConnection(&constraints);
1827
1828 std::string offer_label = "offer_channel";
zhihuang9763d562016-08-05 11:14:50 -07001829 rtc::scoped_refptr<DataChannelInterface> offer_channel =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001830 pc_->CreateDataChannel(offer_label, NULL);
1831
1832 CreateOfferAsLocalDescription();
1833
1834 // Replace the data channel label in the offer and apply it as an answer.
1835 std::string receive_label = "answer_channel";
1836 std::string sdp;
1837 EXPECT_TRUE(pc_->local_description()->ToString(&sdp));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001838 rtc::replace_substrs(offer_label.c_str(), offer_label.length(),
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001839 receive_label.c_str(), receive_label.length(),
1840 &sdp);
1841 CreateAnswerAsRemoteDescription(sdp);
1842
1843 // Verify that a new incoming data channel has been created and that
1844 // it is open but can't we written to.
1845 ASSERT_TRUE(observer_.last_datachannel_ != NULL);
1846 DataChannelInterface* received_channel = observer_.last_datachannel_;
1847 EXPECT_EQ(DataChannelInterface::kConnecting, received_channel->state());
1848 EXPECT_EQ(receive_label, received_channel->label());
1849 EXPECT_FALSE(received_channel->Send(DataBuffer("something")));
1850
1851 // Verify that the channel we initially offered has been rejected.
1852 EXPECT_EQ(DataChannelInterface::kClosed, offer_channel->state());
1853
1854 // Do another offer / answer exchange and verify that the data channel is
1855 // opened.
1856 CreateOfferReceiveAnswer();
1857 EXPECT_EQ_WAIT(DataChannelInterface::kOpen, received_channel->state(),
1858 kTimeout);
1859}
1860
1861// This test that no data channel is returned if a reliable channel is
1862// requested.
1863// TODO(perkj): Remove this test once reliable channels are implemented.
1864TEST_F(PeerConnectionInterfaceTest, CreateReliableRtpDataChannelShouldFail) {
1865 FakeConstraints constraints;
1866 constraints.SetAllowRtpDataChannels();
1867 CreatePeerConnection(&constraints);
1868
1869 std::string label = "test";
1870 webrtc::DataChannelInit config;
1871 config.reliable = true;
zhihuang9763d562016-08-05 11:14:50 -07001872 rtc::scoped_refptr<DataChannelInterface> channel =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001873 pc_->CreateDataChannel(label, &config);
1874 EXPECT_TRUE(channel == NULL);
1875}
1876
deadbeefab9b2d12015-10-14 11:33:11 -07001877// Verifies that duplicated label is not allowed for RTP data channel.
1878TEST_F(PeerConnectionInterfaceTest, RtpDuplicatedLabelNotAllowed) {
1879 FakeConstraints constraints;
1880 constraints.SetAllowRtpDataChannels();
1881 CreatePeerConnection(&constraints);
1882
1883 std::string label = "test";
zhihuang9763d562016-08-05 11:14:50 -07001884 rtc::scoped_refptr<DataChannelInterface> channel =
deadbeefab9b2d12015-10-14 11:33:11 -07001885 pc_->CreateDataChannel(label, nullptr);
1886 EXPECT_NE(channel, nullptr);
1887
zhihuang9763d562016-08-05 11:14:50 -07001888 rtc::scoped_refptr<DataChannelInterface> dup_channel =
deadbeefab9b2d12015-10-14 11:33:11 -07001889 pc_->CreateDataChannel(label, nullptr);
1890 EXPECT_EQ(dup_channel, nullptr);
1891}
1892
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001893// This tests that a SCTP data channel is returned using different
1894// DataChannelInit configurations.
1895TEST_F(PeerConnectionInterfaceTest, CreateSctpDataChannel) {
1896 FakeConstraints constraints;
1897 constraints.SetAllowDtlsSctpDataChannels();
1898 CreatePeerConnection(&constraints);
1899
1900 webrtc::DataChannelInit config;
1901
zhihuang9763d562016-08-05 11:14:50 -07001902 rtc::scoped_refptr<DataChannelInterface> channel =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001903 pc_->CreateDataChannel("1", &config);
1904 EXPECT_TRUE(channel != NULL);
1905 EXPECT_TRUE(channel->reliable());
jiayl@webrtc.org001fd2d2014-05-29 15:31:11 +00001906 EXPECT_TRUE(observer_.renegotiation_needed_);
1907 observer_.renegotiation_needed_ = false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001908
1909 config.ordered = false;
1910 channel = pc_->CreateDataChannel("2", &config);
1911 EXPECT_TRUE(channel != NULL);
1912 EXPECT_TRUE(channel->reliable());
jiayl@webrtc.org001fd2d2014-05-29 15:31:11 +00001913 EXPECT_FALSE(observer_.renegotiation_needed_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001914
1915 config.ordered = true;
1916 config.maxRetransmits = 0;
1917 channel = pc_->CreateDataChannel("3", &config);
1918 EXPECT_TRUE(channel != NULL);
1919 EXPECT_FALSE(channel->reliable());
jiayl@webrtc.org001fd2d2014-05-29 15:31:11 +00001920 EXPECT_FALSE(observer_.renegotiation_needed_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001921
1922 config.maxRetransmits = -1;
1923 config.maxRetransmitTime = 0;
1924 channel = pc_->CreateDataChannel("4", &config);
1925 EXPECT_TRUE(channel != NULL);
1926 EXPECT_FALSE(channel->reliable());
jiayl@webrtc.org001fd2d2014-05-29 15:31:11 +00001927 EXPECT_FALSE(observer_.renegotiation_needed_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001928}
1929
1930// This tests that no data channel is returned if both maxRetransmits and
1931// maxRetransmitTime are set for SCTP data channels.
1932TEST_F(PeerConnectionInterfaceTest,
1933 CreateSctpDataChannelShouldFailForInvalidConfig) {
1934 FakeConstraints constraints;
1935 constraints.SetAllowDtlsSctpDataChannels();
1936 CreatePeerConnection(&constraints);
1937
1938 std::string label = "test";
1939 webrtc::DataChannelInit config;
1940 config.maxRetransmits = 0;
1941 config.maxRetransmitTime = 0;
1942
zhihuang9763d562016-08-05 11:14:50 -07001943 rtc::scoped_refptr<DataChannelInterface> channel =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001944 pc_->CreateDataChannel(label, &config);
1945 EXPECT_TRUE(channel == NULL);
1946}
1947
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001948// The test verifies that creating a SCTP data channel with an id already in use
1949// or out of range should fail.
1950TEST_F(PeerConnectionInterfaceTest,
1951 CreateSctpDataChannelWithInvalidIdShouldFail) {
1952 FakeConstraints constraints;
1953 constraints.SetAllowDtlsSctpDataChannels();
1954 CreatePeerConnection(&constraints);
1955
1956 webrtc::DataChannelInit config;
zhihuang9763d562016-08-05 11:14:50 -07001957 rtc::scoped_refptr<DataChannelInterface> channel;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001958
wu@webrtc.orgcecfd182013-10-30 05:18:12 +00001959 config.id = 1;
1960 channel = pc_->CreateDataChannel("1", &config);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001961 EXPECT_TRUE(channel != NULL);
1962 EXPECT_EQ(1, channel->id());
1963
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001964 channel = pc_->CreateDataChannel("x", &config);
1965 EXPECT_TRUE(channel == NULL);
1966
1967 config.id = cricket::kMaxSctpSid;
1968 channel = pc_->CreateDataChannel("max", &config);
1969 EXPECT_TRUE(channel != NULL);
1970 EXPECT_EQ(config.id, channel->id());
1971
1972 config.id = cricket::kMaxSctpSid + 1;
1973 channel = pc_->CreateDataChannel("x", &config);
1974 EXPECT_TRUE(channel == NULL);
1975}
1976
deadbeefab9b2d12015-10-14 11:33:11 -07001977// Verifies that duplicated label is allowed for SCTP data channel.
1978TEST_F(PeerConnectionInterfaceTest, SctpDuplicatedLabelAllowed) {
1979 FakeConstraints constraints;
1980 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
1981 true);
1982 CreatePeerConnection(&constraints);
1983
1984 std::string label = "test";
zhihuang9763d562016-08-05 11:14:50 -07001985 rtc::scoped_refptr<DataChannelInterface> channel =
deadbeefab9b2d12015-10-14 11:33:11 -07001986 pc_->CreateDataChannel(label, nullptr);
1987 EXPECT_NE(channel, nullptr);
1988
zhihuang9763d562016-08-05 11:14:50 -07001989 rtc::scoped_refptr<DataChannelInterface> dup_channel =
deadbeefab9b2d12015-10-14 11:33:11 -07001990 pc_->CreateDataChannel(label, nullptr);
1991 EXPECT_NE(dup_channel, nullptr);
1992}
1993
jiayl@webrtc.org001fd2d2014-05-29 15:31:11 +00001994// This test verifies that OnRenegotiationNeeded is fired for every new RTP
1995// DataChannel.
1996TEST_F(PeerConnectionInterfaceTest, RenegotiationNeededForNewRtpDataChannel) {
1997 FakeConstraints constraints;
1998 constraints.SetAllowRtpDataChannels();
1999 CreatePeerConnection(&constraints);
2000
zhihuang9763d562016-08-05 11:14:50 -07002001 rtc::scoped_refptr<DataChannelInterface> dc1 =
jiayl@webrtc.org001fd2d2014-05-29 15:31:11 +00002002 pc_->CreateDataChannel("test1", NULL);
2003 EXPECT_TRUE(observer_.renegotiation_needed_);
2004 observer_.renegotiation_needed_ = false;
2005
zhihuang9763d562016-08-05 11:14:50 -07002006 rtc::scoped_refptr<DataChannelInterface> dc2 =
jiayl@webrtc.org001fd2d2014-05-29 15:31:11 +00002007 pc_->CreateDataChannel("test2", NULL);
2008 EXPECT_TRUE(observer_.renegotiation_needed_);
2009}
2010
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002011// This test that a data channel closes when a PeerConnection is deleted/closed.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002012TEST_F(PeerConnectionInterfaceTest, DataChannelCloseWhenPeerConnectionClose) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002013 FakeConstraints constraints;
2014 constraints.SetAllowRtpDataChannels();
2015 CreatePeerConnection(&constraints);
2016
zhihuang9763d562016-08-05 11:14:50 -07002017 rtc::scoped_refptr<DataChannelInterface> data1 =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002018 pc_->CreateDataChannel("test1", NULL);
zhihuang9763d562016-08-05 11:14:50 -07002019 rtc::scoped_refptr<DataChannelInterface> data2 =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002020 pc_->CreateDataChannel("test2", NULL);
2021 ASSERT_TRUE(data1 != NULL);
kwibergd1fe2812016-04-27 06:47:29 -07002022 std::unique_ptr<MockDataChannelObserver> observer1(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002023 new MockDataChannelObserver(data1));
kwibergd1fe2812016-04-27 06:47:29 -07002024 std::unique_ptr<MockDataChannelObserver> observer2(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002025 new MockDataChannelObserver(data2));
2026
2027 CreateOfferReceiveAnswer();
2028 EXPECT_TRUE_WAIT(observer1->IsOpen(), kTimeout);
2029 EXPECT_TRUE_WAIT(observer2->IsOpen(), kTimeout);
2030
2031 ReleasePeerConnection();
2032 EXPECT_EQ(DataChannelInterface::kClosed, data1->state());
2033 EXPECT_EQ(DataChannelInterface::kClosed, data2->state());
2034}
2035
2036// This test that data channels can be rejected in an answer.
2037TEST_F(PeerConnectionInterfaceTest, TestRejectDataChannelInAnswer) {
2038 FakeConstraints constraints;
2039 constraints.SetAllowRtpDataChannels();
2040 CreatePeerConnection(&constraints);
2041
zhihuang9763d562016-08-05 11:14:50 -07002042 rtc::scoped_refptr<DataChannelInterface> offer_channel(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002043 pc_->CreateDataChannel("offer_channel", NULL));
2044
2045 CreateOfferAsLocalDescription();
2046
2047 // Create an answer where the m-line for data channels are rejected.
2048 std::string sdp;
2049 EXPECT_TRUE(pc_->local_description()->ToString(&sdp));
2050 webrtc::JsepSessionDescription* answer = new webrtc::JsepSessionDescription(
2051 SessionDescriptionInterface::kAnswer);
2052 EXPECT_TRUE(answer->Initialize(sdp, NULL));
2053 cricket::ContentInfo* data_info =
2054 answer->description()->GetContentByName("data");
2055 data_info->rejected = true;
2056
2057 DoSetRemoteDescription(answer);
2058 EXPECT_EQ(DataChannelInterface::kClosed, offer_channel->state());
2059}
2060
2061// Test that we can create a session description from an SDP string from
2062// FireFox, use it as a remote session description, generate an answer and use
2063// the answer as a local description.
Taylor Brandstetter7ff17372016-04-01 11:50:39 -07002064TEST_F(PeerConnectionInterfaceTest, ReceiveFireFoxOffer) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002065 FakeConstraints constraints;
2066 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2067 true);
2068 CreatePeerConnection(&constraints);
2069 AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label");
2070 SessionDescriptionInterface* desc =
2071 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer,
jbauchfabe2c92015-07-16 13:43:14 -07002072 webrtc::kFireFoxSdpOffer, nullptr);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002073 EXPECT_TRUE(DoSetSessionDescription(desc, false));
2074 CreateAnswerAsLocalDescription();
2075 ASSERT_TRUE(pc_->local_description() != NULL);
2076 ASSERT_TRUE(pc_->remote_description() != NULL);
2077
2078 const cricket::ContentInfo* content =
2079 cricket::GetFirstAudioContent(pc_->local_description()->description());
2080 ASSERT_TRUE(content != NULL);
2081 EXPECT_FALSE(content->rejected);
2082
2083 content =
2084 cricket::GetFirstVideoContent(pc_->local_description()->description());
2085 ASSERT_TRUE(content != NULL);
2086 EXPECT_FALSE(content->rejected);
sergeyu@chromium.orga23f0ca2013-11-13 22:48:52 +00002087#ifdef HAVE_SCTP
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002088 content =
2089 cricket::GetFirstDataContent(pc_->local_description()->description());
2090 ASSERT_TRUE(content != NULL);
2091 EXPECT_TRUE(content->rejected);
sergeyu@chromium.orga23f0ca2013-11-13 22:48:52 +00002092#endif
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002093}
2094
deadbeef8662f942017-01-20 21:20:51 -08002095// Test that an offer can be received which offers DTLS with SDES fallback.
2096// Regression test for issue:
2097// https://bugs.chromium.org/p/webrtc/issues/detail?id=6972
2098TEST_F(PeerConnectionInterfaceTest, ReceiveDtlsSdesFallbackOffer) {
2099 FakeConstraints constraints;
2100 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2101 true);
2102 CreatePeerConnection(&constraints);
2103 // Wait for fake certificate to be generated. Previously, this is what caused
2104 // the "a=crypto" lines to be rejected.
2105 AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label");
2106 ASSERT_NE(nullptr, fake_certificate_generator_);
2107 EXPECT_EQ_WAIT(1, fake_certificate_generator_->generated_certificates(),
2108 kTimeout);
2109 SessionDescriptionInterface* desc = webrtc::CreateSessionDescription(
2110 SessionDescriptionInterface::kOffer, kDtlsSdesFallbackSdp, nullptr);
2111 EXPECT_TRUE(DoSetSessionDescription(desc, false));
2112 CreateAnswerAsLocalDescription();
2113}
2114
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002115// Test that we can create an audio only offer and receive an answer with a
2116// limited set of audio codecs and receive an updated offer with more audio
2117// codecs, where the added codecs are not supported.
2118TEST_F(PeerConnectionInterfaceTest, ReceiveUpdatedAudioOfferWithBadCodecs) {
deadbeef293e9262017-01-11 12:28:30 -08002119 CreatePeerConnectionWithoutDtls();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002120 AddVoiceStream("audio_label");
2121 CreateOfferAsLocalDescription();
2122
2123 SessionDescriptionInterface* answer =
2124 webrtc::CreateSessionDescription(SessionDescriptionInterface::kAnswer,
jbauchfabe2c92015-07-16 13:43:14 -07002125 webrtc::kAudioSdp, nullptr);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002126 EXPECT_TRUE(DoSetSessionDescription(answer, false));
2127
2128 SessionDescriptionInterface* updated_offer =
2129 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer,
jbauchfabe2c92015-07-16 13:43:14 -07002130 webrtc::kAudioSdpWithUnsupportedCodecs,
2131 nullptr);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002132 EXPECT_TRUE(DoSetSessionDescription(updated_offer, false));
2133 CreateAnswerAsLocalDescription();
2134}
2135
deadbeefc80741f2015-10-22 13:14:45 -07002136// Test that if we're receiving (but not sending) a track, subsequent offers
2137// will have m-lines with a=recvonly.
2138TEST_F(PeerConnectionInterfaceTest, CreateSubsequentRecvOnlyOffer) {
2139 FakeConstraints constraints;
2140 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2141 true);
2142 CreatePeerConnection(&constraints);
2143 CreateAndSetRemoteOffer(kSdpStringWithStream1);
2144 CreateAnswerAsLocalDescription();
2145
2146 // At this point we should be receiving stream 1, but not sending anything.
2147 // A new offer should be recvonly.
kwibergd1fe2812016-04-27 06:47:29 -07002148 std::unique_ptr<SessionDescriptionInterface> offer;
deadbeefc80741f2015-10-22 13:14:45 -07002149 DoCreateOffer(&offer, nullptr);
2150
2151 const cricket::ContentInfo* video_content =
2152 cricket::GetFirstVideoContent(offer->description());
2153 const cricket::VideoContentDescription* video_desc =
2154 static_cast<const cricket::VideoContentDescription*>(
2155 video_content->description);
2156 ASSERT_EQ(cricket::MD_RECVONLY, video_desc->direction());
2157
2158 const cricket::ContentInfo* audio_content =
2159 cricket::GetFirstAudioContent(offer->description());
2160 const cricket::AudioContentDescription* audio_desc =
2161 static_cast<const cricket::AudioContentDescription*>(
2162 audio_content->description);
2163 ASSERT_EQ(cricket::MD_RECVONLY, audio_desc->direction());
2164}
2165
2166// Test that if we're receiving (but not sending) a track, and the
2167// offerToReceiveVideo/offerToReceiveAudio constraints are explicitly set to
2168// false, the generated m-lines will be a=inactive.
2169TEST_F(PeerConnectionInterfaceTest, CreateSubsequentInactiveOffer) {
2170 FakeConstraints constraints;
2171 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2172 true);
2173 CreatePeerConnection(&constraints);
2174 CreateAndSetRemoteOffer(kSdpStringWithStream1);
2175 CreateAnswerAsLocalDescription();
2176
2177 // At this point we should be receiving stream 1, but not sending anything.
2178 // A new offer would be recvonly, but we'll set the "no receive" constraints
2179 // to make it inactive.
kwibergd1fe2812016-04-27 06:47:29 -07002180 std::unique_ptr<SessionDescriptionInterface> offer;
deadbeefc80741f2015-10-22 13:14:45 -07002181 FakeConstraints offer_constraints;
2182 offer_constraints.AddMandatory(
2183 webrtc::MediaConstraintsInterface::kOfferToReceiveVideo, false);
2184 offer_constraints.AddMandatory(
2185 webrtc::MediaConstraintsInterface::kOfferToReceiveAudio, false);
2186 DoCreateOffer(&offer, &offer_constraints);
2187
2188 const cricket::ContentInfo* video_content =
2189 cricket::GetFirstVideoContent(offer->description());
2190 const cricket::VideoContentDescription* video_desc =
2191 static_cast<const cricket::VideoContentDescription*>(
2192 video_content->description);
2193 ASSERT_EQ(cricket::MD_INACTIVE, video_desc->direction());
2194
2195 const cricket::ContentInfo* audio_content =
2196 cricket::GetFirstAudioContent(offer->description());
2197 const cricket::AudioContentDescription* audio_desc =
2198 static_cast<const cricket::AudioContentDescription*>(
2199 audio_content->description);
2200 ASSERT_EQ(cricket::MD_INACTIVE, audio_desc->direction());
2201}
2202
deadbeef653b8e02015-11-11 12:55:10 -08002203// Test that we can use SetConfiguration to change the ICE servers of the
2204// PortAllocator.
2205TEST_F(PeerConnectionInterfaceTest, SetConfigurationChangesIceServers) {
2206 CreatePeerConnection();
2207
2208 PeerConnectionInterface::RTCConfiguration config;
2209 PeerConnectionInterface::IceServer server;
2210 server.uri = "stun:test_hostname";
2211 config.servers.push_back(server);
2212 EXPECT_TRUE(pc_->SetConfiguration(config));
2213
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -08002214 EXPECT_EQ(1u, port_allocator_->stun_servers().size());
2215 EXPECT_EQ("test_hostname",
2216 port_allocator_->stun_servers().begin()->hostname());
deadbeef653b8e02015-11-11 12:55:10 -08002217}
2218
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002219TEST_F(PeerConnectionInterfaceTest, SetConfigurationChangesCandidateFilter) {
2220 CreatePeerConnection();
2221 PeerConnectionInterface::RTCConfiguration config;
2222 config.type = PeerConnectionInterface::kRelay;
2223 EXPECT_TRUE(pc_->SetConfiguration(config));
2224 EXPECT_EQ(cricket::CF_RELAY, port_allocator_->candidate_filter());
2225}
2226
deadbeef293e9262017-01-11 12:28:30 -08002227TEST_F(PeerConnectionInterfaceTest, SetConfigurationChangesPruneTurnPortsFlag) {
2228 PeerConnectionInterface::RTCConfiguration config;
2229 config.prune_turn_ports = false;
2230 CreatePeerConnection(config, nullptr);
2231 EXPECT_FALSE(port_allocator_->prune_turn_ports());
2232
2233 config.prune_turn_ports = true;
2234 EXPECT_TRUE(pc_->SetConfiguration(config));
2235 EXPECT_TRUE(port_allocator_->prune_turn_ports());
2236}
2237
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002238// Test that when SetConfiguration changes both the pool size and other
2239// attributes, the pooled session is created with the updated attributes.
2240TEST_F(PeerConnectionInterfaceTest,
2241 SetConfigurationCreatesPooledSessionCorrectly) {
2242 CreatePeerConnection();
2243 PeerConnectionInterface::RTCConfiguration config;
2244 config.ice_candidate_pool_size = 1;
2245 PeerConnectionInterface::IceServer server;
2246 server.uri = kStunAddressOnly;
2247 config.servers.push_back(server);
2248 config.type = PeerConnectionInterface::kRelay;
Taylor Brandstetter417eebe2016-05-23 16:02:19 -07002249 EXPECT_TRUE(pc_->SetConfiguration(config));
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002250
2251 const cricket::FakePortAllocatorSession* session =
2252 static_cast<const cricket::FakePortAllocatorSession*>(
2253 port_allocator_->GetPooledSession());
2254 ASSERT_NE(nullptr, session);
2255 EXPECT_EQ(1UL, session->stun_servers().size());
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002256}
2257
deadbeef293e9262017-01-11 12:28:30 -08002258// Test that after SetLocalDescription, changing the pool size is not allowed,
2259// and an invalid modification error is returned.
deadbeef6de92f92016-12-12 18:49:32 -08002260TEST_F(PeerConnectionInterfaceTest,
2261 CantChangePoolSizeAfterSetLocalDescription) {
2262 CreatePeerConnection();
2263 // Start by setting a size of 1.
2264 PeerConnectionInterface::RTCConfiguration config;
2265 config.ice_candidate_pool_size = 1;
2266 EXPECT_TRUE(pc_->SetConfiguration(config));
2267
2268 // Set remote offer; can still change pool size at this point.
2269 CreateOfferAsRemoteDescription();
2270 config.ice_candidate_pool_size = 2;
2271 EXPECT_TRUE(pc_->SetConfiguration(config));
2272
2273 // Set local answer; now it's too late.
2274 CreateAnswerAsLocalDescription();
2275 config.ice_candidate_pool_size = 3;
deadbeef293e9262017-01-11 12:28:30 -08002276 RTCError error;
2277 EXPECT_FALSE(pc_->SetConfiguration(config, &error));
2278 EXPECT_EQ(RTCErrorType::INVALID_MODIFICATION, error.type());
2279}
2280
2281// Test that SetConfiguration returns an invalid modification error if
2282// modifying a field in the configuration that isn't allowed to be modified.
2283TEST_F(PeerConnectionInterfaceTest,
2284 SetConfigurationReturnsInvalidModificationError) {
2285 PeerConnectionInterface::RTCConfiguration config;
2286 config.bundle_policy = PeerConnectionInterface::kBundlePolicyBalanced;
2287 config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyNegotiate;
2288 config.continual_gathering_policy = PeerConnectionInterface::GATHER_ONCE;
2289 CreatePeerConnection(config, nullptr);
2290
2291 PeerConnectionInterface::RTCConfiguration modified_config = config;
2292 modified_config.bundle_policy =
2293 PeerConnectionInterface::kBundlePolicyMaxBundle;
2294 RTCError error;
2295 EXPECT_FALSE(pc_->SetConfiguration(modified_config, &error));
2296 EXPECT_EQ(RTCErrorType::INVALID_MODIFICATION, error.type());
2297
2298 modified_config = config;
2299 modified_config.rtcp_mux_policy =
2300 PeerConnectionInterface::kRtcpMuxPolicyRequire;
2301 error.set_type(RTCErrorType::NONE);
2302 EXPECT_FALSE(pc_->SetConfiguration(modified_config, &error));
2303 EXPECT_EQ(RTCErrorType::INVALID_MODIFICATION, error.type());
2304
2305 modified_config = config;
2306 modified_config.continual_gathering_policy =
2307 PeerConnectionInterface::GATHER_CONTINUALLY;
2308 error.set_type(RTCErrorType::NONE);
2309 EXPECT_FALSE(pc_->SetConfiguration(modified_config, &error));
2310 EXPECT_EQ(RTCErrorType::INVALID_MODIFICATION, error.type());
2311}
2312
2313// Test that SetConfiguration returns a range error if the candidate pool size
2314// is negative or larger than allowed by the spec.
2315TEST_F(PeerConnectionInterfaceTest,
2316 SetConfigurationReturnsRangeErrorForBadCandidatePoolSize) {
2317 PeerConnectionInterface::RTCConfiguration config;
2318 CreatePeerConnection(config, nullptr);
2319
2320 config.ice_candidate_pool_size = -1;
2321 RTCError error;
2322 EXPECT_FALSE(pc_->SetConfiguration(config, &error));
2323 EXPECT_EQ(RTCErrorType::INVALID_RANGE, error.type());
2324
2325 config.ice_candidate_pool_size = INT_MAX;
2326 error.set_type(RTCErrorType::NONE);
2327 EXPECT_FALSE(pc_->SetConfiguration(config, &error));
2328 EXPECT_EQ(RTCErrorType::INVALID_RANGE, error.type());
2329}
2330
2331// Test that SetConfiguration returns a syntax error if parsing an ICE server
2332// URL failed.
2333TEST_F(PeerConnectionInterfaceTest,
2334 SetConfigurationReturnsSyntaxErrorFromBadIceUrls) {
2335 PeerConnectionInterface::RTCConfiguration config;
2336 CreatePeerConnection(config, nullptr);
2337
2338 PeerConnectionInterface::IceServer bad_server;
2339 bad_server.uri = "stunn:www.example.com";
2340 config.servers.push_back(bad_server);
2341 RTCError error;
2342 EXPECT_FALSE(pc_->SetConfiguration(config, &error));
2343 EXPECT_EQ(RTCErrorType::SYNTAX_ERROR, error.type());
2344}
2345
2346// Test that SetConfiguration returns an invalid parameter error if a TURN
2347// IceServer is missing a username or password.
2348TEST_F(PeerConnectionInterfaceTest,
2349 SetConfigurationReturnsInvalidParameterIfCredentialsMissing) {
2350 PeerConnectionInterface::RTCConfiguration config;
2351 CreatePeerConnection(config, nullptr);
2352
2353 PeerConnectionInterface::IceServer bad_server;
2354 bad_server.uri = "turn:www.example.com";
2355 // Missing password.
2356 bad_server.username = "foo";
2357 config.servers.push_back(bad_server);
2358 RTCError error;
2359 EXPECT_FALSE(pc_->SetConfiguration(config, &error));
2360 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, error.type());
deadbeef6de92f92016-12-12 18:49:32 -08002361}
2362
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002363// Test that PeerConnection::Close changes the states to closed and all remote
2364// tracks change state to ended.
2365TEST_F(PeerConnectionInterfaceTest, CloseAndTestStreamsAndStates) {
2366 // Initialize a PeerConnection and negotiate local and remote session
2367 // description.
2368 InitiateCall();
2369 ASSERT_EQ(1u, pc_->local_streams()->count());
2370 ASSERT_EQ(1u, pc_->remote_streams()->count());
2371
2372 pc_->Close();
2373
2374 EXPECT_EQ(PeerConnectionInterface::kClosed, pc_->signaling_state());
2375 EXPECT_EQ(PeerConnectionInterface::kIceConnectionClosed,
2376 pc_->ice_connection_state());
2377 EXPECT_EQ(PeerConnectionInterface::kIceGatheringComplete,
2378 pc_->ice_gathering_state());
2379
2380 EXPECT_EQ(1u, pc_->local_streams()->count());
2381 EXPECT_EQ(1u, pc_->remote_streams()->count());
2382
zhihuang9763d562016-08-05 11:14:50 -07002383 rtc::scoped_refptr<MediaStreamInterface> remote_stream =
2384 pc_->remote_streams()->at(0);
Taylor Brandstetterd45b95c2016-03-29 13:16:52 -07002385 // Track state may be updated asynchronously.
perkjd61bf802016-03-24 03:16:19 -07002386 EXPECT_EQ_WAIT(MediaStreamTrackInterface::kEnded,
Taylor Brandstetterd45b95c2016-03-29 13:16:52 -07002387 remote_stream->GetAudioTracks()[0]->state(), kTimeout);
2388 EXPECT_EQ_WAIT(MediaStreamTrackInterface::kEnded,
2389 remote_stream->GetVideoTracks()[0]->state(), kTimeout);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002390}
2391
2392// Test that PeerConnection methods fails gracefully after
2393// PeerConnection::Close has been called.
2394TEST_F(PeerConnectionInterfaceTest, CloseAndTestMethods) {
deadbeef293e9262017-01-11 12:28:30 -08002395 CreatePeerConnectionWithoutDtls();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002396 AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label");
2397 CreateOfferAsRemoteDescription();
2398 CreateAnswerAsLocalDescription();
2399
2400 ASSERT_EQ(1u, pc_->local_streams()->count());
zhihuang9763d562016-08-05 11:14:50 -07002401 rtc::scoped_refptr<MediaStreamInterface> local_stream =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002402 pc_->local_streams()->at(0);
2403
2404 pc_->Close();
2405
2406 pc_->RemoveStream(local_stream);
perkj@webrtc.orgc2dd5ee2014-11-04 11:31:29 +00002407 EXPECT_FALSE(pc_->AddStream(local_stream));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002408
2409 ASSERT_FALSE(local_stream->GetAudioTracks().empty());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002410 rtc::scoped_refptr<webrtc::DtmfSenderInterface> dtmf_sender(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002411 pc_->CreateDtmfSender(local_stream->GetAudioTracks()[0]));
wu@webrtc.org66037362013-08-13 00:09:35 +00002412 EXPECT_TRUE(NULL == dtmf_sender); // local stream has been removed.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002413
2414 EXPECT_TRUE(pc_->CreateDataChannel("test", NULL) == NULL);
2415
2416 EXPECT_TRUE(pc_->local_description() != NULL);
2417 EXPECT_TRUE(pc_->remote_description() != NULL);
2418
kwibergd1fe2812016-04-27 06:47:29 -07002419 std::unique_ptr<SessionDescriptionInterface> offer;
kwiberg2bbff992016-03-16 11:03:04 -07002420 EXPECT_TRUE(DoCreateOffer(&offer, nullptr));
kwibergd1fe2812016-04-27 06:47:29 -07002421 std::unique_ptr<SessionDescriptionInterface> answer;
kwiberg2bbff992016-03-16 11:03:04 -07002422 EXPECT_TRUE(DoCreateAnswer(&answer, nullptr));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002423
2424 std::string sdp;
2425 ASSERT_TRUE(pc_->remote_description()->ToString(&sdp));
2426 SessionDescriptionInterface* remote_offer =
2427 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer,
2428 sdp, NULL);
2429 EXPECT_FALSE(DoSetRemoteDescription(remote_offer));
2430
2431 ASSERT_TRUE(pc_->local_description()->ToString(&sdp));
2432 SessionDescriptionInterface* local_offer =
2433 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer,
2434 sdp, NULL);
2435 EXPECT_FALSE(DoSetLocalDescription(local_offer));
2436}
2437
2438// Test that GetStats can still be called after PeerConnection::Close.
2439TEST_F(PeerConnectionInterfaceTest, CloseAndGetStats) {
2440 InitiateCall();
2441 pc_->Close();
2442 DoGetStats(NULL);
2443}
deadbeefab9b2d12015-10-14 11:33:11 -07002444
2445// NOTE: The series of tests below come from what used to be
2446// mediastreamsignaling_unittest.cc, and are mostly aimed at testing that
2447// setting a remote or local description has the expected effects.
2448
2449// This test verifies that the remote MediaStreams corresponding to a received
2450// SDP string is created. In this test the two separate MediaStreams are
2451// signaled.
2452TEST_F(PeerConnectionInterfaceTest, UpdateRemoteStreams) {
2453 FakeConstraints constraints;
2454 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2455 true);
2456 CreatePeerConnection(&constraints);
2457 CreateAndSetRemoteOffer(kSdpStringWithStream1);
2458
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002459 rtc::scoped_refptr<StreamCollection> reference(CreateStreamCollection(1, 1));
deadbeefab9b2d12015-10-14 11:33:11 -07002460 EXPECT_TRUE(
2461 CompareStreamCollections(observer_.remote_streams(), reference.get()));
2462 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
2463 EXPECT_TRUE(remote_stream->GetVideoTracks()[0]->GetSource() != nullptr);
2464
2465 // Create a session description based on another SDP with another
2466 // MediaStream.
2467 CreateAndSetRemoteOffer(kSdpStringWithStream1And2);
2468
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002469 rtc::scoped_refptr<StreamCollection> reference2(CreateStreamCollection(2, 1));
deadbeefab9b2d12015-10-14 11:33:11 -07002470 EXPECT_TRUE(
2471 CompareStreamCollections(observer_.remote_streams(), reference2.get()));
2472}
2473
2474// This test verifies that when remote tracks are added/removed from SDP, the
2475// created remote streams are updated appropriately.
2476TEST_F(PeerConnectionInterfaceTest,
2477 AddRemoveTrackFromExistingRemoteMediaStream) {
2478 FakeConstraints constraints;
2479 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2480 true);
2481 CreatePeerConnection(&constraints);
kwibergd1fe2812016-04-27 06:47:29 -07002482 std::unique_ptr<SessionDescriptionInterface> desc_ms1 =
kwiberg2bbff992016-03-16 11:03:04 -07002483 CreateSessionDescriptionAndReference(1, 1);
deadbeefab9b2d12015-10-14 11:33:11 -07002484 EXPECT_TRUE(DoSetRemoteDescription(desc_ms1.release()));
2485 EXPECT_TRUE(CompareStreamCollections(observer_.remote_streams(),
2486 reference_collection_));
2487
2488 // Add extra audio and video tracks to the same MediaStream.
kwibergd1fe2812016-04-27 06:47:29 -07002489 std::unique_ptr<SessionDescriptionInterface> desc_ms1_two_tracks =
kwiberg2bbff992016-03-16 11:03:04 -07002490 CreateSessionDescriptionAndReference(2, 2);
deadbeefab9b2d12015-10-14 11:33:11 -07002491 EXPECT_TRUE(DoSetRemoteDescription(desc_ms1_two_tracks.release()));
2492 EXPECT_TRUE(CompareStreamCollections(observer_.remote_streams(),
2493 reference_collection_));
zhihuang9763d562016-08-05 11:14:50 -07002494 rtc::scoped_refptr<AudioTrackInterface> audio_track2 =
perkjd61bf802016-03-24 03:16:19 -07002495 observer_.remote_streams()->at(0)->GetAudioTracks()[1];
2496 EXPECT_EQ(webrtc::MediaStreamTrackInterface::kLive, audio_track2->state());
zhihuang9763d562016-08-05 11:14:50 -07002497 rtc::scoped_refptr<VideoTrackInterface> video_track2 =
perkjd61bf802016-03-24 03:16:19 -07002498 observer_.remote_streams()->at(0)->GetVideoTracks()[1];
2499 EXPECT_EQ(webrtc::MediaStreamTrackInterface::kLive, video_track2->state());
deadbeefab9b2d12015-10-14 11:33:11 -07002500
2501 // Remove the extra audio and video tracks.
kwibergd1fe2812016-04-27 06:47:29 -07002502 std::unique_ptr<SessionDescriptionInterface> desc_ms2 =
kwiberg2bbff992016-03-16 11:03:04 -07002503 CreateSessionDescriptionAndReference(1, 1);
perkjd61bf802016-03-24 03:16:19 -07002504 MockTrackObserver audio_track_observer(audio_track2);
2505 MockTrackObserver video_track_observer(video_track2);
2506
2507 EXPECT_CALL(audio_track_observer, OnChanged()).Times(Exactly(1));
2508 EXPECT_CALL(video_track_observer, OnChanged()).Times(Exactly(1));
deadbeefab9b2d12015-10-14 11:33:11 -07002509 EXPECT_TRUE(DoSetRemoteDescription(desc_ms2.release()));
2510 EXPECT_TRUE(CompareStreamCollections(observer_.remote_streams(),
2511 reference_collection_));
Taylor Brandstetterd45b95c2016-03-29 13:16:52 -07002512 // Track state may be updated asynchronously.
perkjd61bf802016-03-24 03:16:19 -07002513 EXPECT_EQ_WAIT(webrtc::MediaStreamTrackInterface::kEnded,
Taylor Brandstetterd45b95c2016-03-29 13:16:52 -07002514 audio_track2->state(), kTimeout);
2515 EXPECT_EQ_WAIT(webrtc::MediaStreamTrackInterface::kEnded,
2516 video_track2->state(), kTimeout);
deadbeefab9b2d12015-10-14 11:33:11 -07002517}
2518
2519// This tests that remote tracks are ended if a local session description is set
2520// that rejects the media content type.
2521TEST_F(PeerConnectionInterfaceTest, RejectMediaContent) {
2522 FakeConstraints constraints;
2523 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2524 true);
2525 CreatePeerConnection(&constraints);
2526 // First create and set a remote offer, then reject its video content in our
2527 // answer.
2528 CreateAndSetRemoteOffer(kSdpStringWithStream1);
2529 ASSERT_EQ(1u, observer_.remote_streams()->count());
2530 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
2531 ASSERT_EQ(1u, remote_stream->GetVideoTracks().size());
2532 ASSERT_EQ(1u, remote_stream->GetAudioTracks().size());
2533
2534 rtc::scoped_refptr<webrtc::VideoTrackInterface> remote_video =
2535 remote_stream->GetVideoTracks()[0];
2536 EXPECT_EQ(webrtc::MediaStreamTrackInterface::kLive, remote_video->state());
2537 rtc::scoped_refptr<webrtc::AudioTrackInterface> remote_audio =
2538 remote_stream->GetAudioTracks()[0];
2539 EXPECT_EQ(webrtc::MediaStreamTrackInterface::kLive, remote_audio->state());
2540
kwibergd1fe2812016-04-27 06:47:29 -07002541 std::unique_ptr<SessionDescriptionInterface> local_answer;
kwiberg2bbff992016-03-16 11:03:04 -07002542 EXPECT_TRUE(DoCreateAnswer(&local_answer, nullptr));
deadbeefab9b2d12015-10-14 11:33:11 -07002543 cricket::ContentInfo* video_info =
2544 local_answer->description()->GetContentByName("video");
2545 video_info->rejected = true;
2546 EXPECT_TRUE(DoSetLocalDescription(local_answer.release()));
2547 EXPECT_EQ(webrtc::MediaStreamTrackInterface::kEnded, remote_video->state());
2548 EXPECT_EQ(webrtc::MediaStreamTrackInterface::kLive, remote_audio->state());
2549
2550 // Now create an offer where we reject both video and audio.
kwibergd1fe2812016-04-27 06:47:29 -07002551 std::unique_ptr<SessionDescriptionInterface> local_offer;
kwiberg2bbff992016-03-16 11:03:04 -07002552 EXPECT_TRUE(DoCreateOffer(&local_offer, nullptr));
deadbeefab9b2d12015-10-14 11:33:11 -07002553 video_info = local_offer->description()->GetContentByName("video");
2554 ASSERT_TRUE(video_info != nullptr);
2555 video_info->rejected = true;
2556 cricket::ContentInfo* audio_info =
2557 local_offer->description()->GetContentByName("audio");
2558 ASSERT_TRUE(audio_info != nullptr);
2559 audio_info->rejected = true;
2560 EXPECT_TRUE(DoSetLocalDescription(local_offer.release()));
Taylor Brandstetterd45b95c2016-03-29 13:16:52 -07002561 // Track state may be updated asynchronously.
perkjd61bf802016-03-24 03:16:19 -07002562 EXPECT_EQ_WAIT(webrtc::MediaStreamTrackInterface::kEnded,
Taylor Brandstetterd45b95c2016-03-29 13:16:52 -07002563 remote_audio->state(), kTimeout);
2564 EXPECT_EQ_WAIT(webrtc::MediaStreamTrackInterface::kEnded,
2565 remote_video->state(), kTimeout);
deadbeefab9b2d12015-10-14 11:33:11 -07002566}
2567
2568// This tests that we won't crash if the remote track has been removed outside
2569// of PeerConnection and then PeerConnection tries to reject the track.
2570TEST_F(PeerConnectionInterfaceTest, RemoveTrackThenRejectMediaContent) {
2571 FakeConstraints constraints;
2572 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2573 true);
2574 CreatePeerConnection(&constraints);
2575 CreateAndSetRemoteOffer(kSdpStringWithStream1);
2576 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
2577 remote_stream->RemoveTrack(remote_stream->GetVideoTracks()[0]);
2578 remote_stream->RemoveTrack(remote_stream->GetAudioTracks()[0]);
2579
kwibergd1fe2812016-04-27 06:47:29 -07002580 std::unique_ptr<SessionDescriptionInterface> local_answer(
deadbeefab9b2d12015-10-14 11:33:11 -07002581 webrtc::CreateSessionDescription(SessionDescriptionInterface::kAnswer,
2582 kSdpStringWithStream1, nullptr));
2583 cricket::ContentInfo* video_info =
2584 local_answer->description()->GetContentByName("video");
2585 video_info->rejected = true;
2586 cricket::ContentInfo* audio_info =
2587 local_answer->description()->GetContentByName("audio");
2588 audio_info->rejected = true;
2589 EXPECT_TRUE(DoSetLocalDescription(local_answer.release()));
2590
2591 // No crash is a pass.
2592}
2593
deadbeef5e97fb52015-10-15 12:49:08 -07002594// This tests that if a recvonly remote description is set, no remote streams
2595// will be created, even if the description contains SSRCs/MSIDs.
2596// See: https://code.google.com/p/webrtc/issues/detail?id=5054
2597TEST_F(PeerConnectionInterfaceTest, RecvonlyDescriptionDoesntCreateStream) {
2598 FakeConstraints constraints;
2599 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2600 true);
2601 CreatePeerConnection(&constraints);
2602
2603 std::string recvonly_offer = kSdpStringWithStream1;
2604 rtc::replace_substrs(kSendrecv, strlen(kSendrecv), kRecvonly,
2605 strlen(kRecvonly), &recvonly_offer);
2606 CreateAndSetRemoteOffer(recvonly_offer);
2607
2608 EXPECT_EQ(0u, observer_.remote_streams()->count());
2609}
2610
deadbeefab9b2d12015-10-14 11:33:11 -07002611// This tests that a default MediaStream is created if a remote session
2612// description doesn't contain any streams and no MSID support.
2613// It also tests that the default stream is updated if a video m-line is added
2614// in a subsequent session description.
Taylor Brandstetter7ff17372016-04-01 11:50:39 -07002615TEST_F(PeerConnectionInterfaceTest, SdpWithoutMsidCreatesDefaultStream) {
deadbeefab9b2d12015-10-14 11:33:11 -07002616 FakeConstraints constraints;
2617 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2618 true);
2619 CreatePeerConnection(&constraints);
2620 CreateAndSetRemoteOffer(kSdpStringWithoutStreamsAudioOnly);
2621
2622 ASSERT_EQ(1u, observer_.remote_streams()->count());
2623 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
2624
2625 EXPECT_EQ(1u, remote_stream->GetAudioTracks().size());
2626 EXPECT_EQ(0u, remote_stream->GetVideoTracks().size());
2627 EXPECT_EQ("default", remote_stream->label());
2628
2629 CreateAndSetRemoteOffer(kSdpStringWithoutStreams);
2630 ASSERT_EQ(1u, observer_.remote_streams()->count());
2631 ASSERT_EQ(1u, remote_stream->GetAudioTracks().size());
2632 EXPECT_EQ("defaulta0", remote_stream->GetAudioTracks()[0]->id());
deadbeef884f5852016-01-15 09:20:04 -08002633 EXPECT_EQ(MediaStreamTrackInterface::kLive,
2634 remote_stream->GetAudioTracks()[0]->state());
deadbeefab9b2d12015-10-14 11:33:11 -07002635 ASSERT_EQ(1u, remote_stream->GetVideoTracks().size());
2636 EXPECT_EQ("defaultv0", remote_stream->GetVideoTracks()[0]->id());
deadbeef884f5852016-01-15 09:20:04 -08002637 EXPECT_EQ(MediaStreamTrackInterface::kLive,
2638 remote_stream->GetVideoTracks()[0]->state());
deadbeefab9b2d12015-10-14 11:33:11 -07002639}
2640
2641// This tests that a default MediaStream is created if a remote session
2642// description doesn't contain any streams and media direction is send only.
2643TEST_F(PeerConnectionInterfaceTest,
Taylor Brandstetter7ff17372016-04-01 11:50:39 -07002644 SendOnlySdpWithoutMsidCreatesDefaultStream) {
deadbeefab9b2d12015-10-14 11:33:11 -07002645 FakeConstraints constraints;
2646 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2647 true);
2648 CreatePeerConnection(&constraints);
2649 CreateAndSetRemoteOffer(kSdpStringSendOnlyWithoutStreams);
2650
2651 ASSERT_EQ(1u, observer_.remote_streams()->count());
2652 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
2653
2654 EXPECT_EQ(1u, remote_stream->GetAudioTracks().size());
2655 EXPECT_EQ(1u, remote_stream->GetVideoTracks().size());
2656 EXPECT_EQ("default", remote_stream->label());
2657}
2658
2659// This tests that it won't crash when PeerConnection tries to remove
2660// a remote track that as already been removed from the MediaStream.
2661TEST_F(PeerConnectionInterfaceTest, RemoveAlreadyGoneRemoteStream) {
2662 FakeConstraints constraints;
2663 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2664 true);
2665 CreatePeerConnection(&constraints);
2666 CreateAndSetRemoteOffer(kSdpStringWithStream1);
2667 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
2668 remote_stream->RemoveTrack(remote_stream->GetAudioTracks()[0]);
2669 remote_stream->RemoveTrack(remote_stream->GetVideoTracks()[0]);
2670
2671 CreateAndSetRemoteOffer(kSdpStringWithoutStreams);
2672
2673 // No crash is a pass.
2674}
2675
2676// This tests that a default MediaStream is created if the remote session
2677// description doesn't contain any streams and don't contain an indication if
2678// MSID is supported.
2679TEST_F(PeerConnectionInterfaceTest,
Taylor Brandstetter7ff17372016-04-01 11:50:39 -07002680 SdpWithoutMsidAndStreamsCreatesDefaultStream) {
deadbeefab9b2d12015-10-14 11:33:11 -07002681 FakeConstraints constraints;
2682 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2683 true);
2684 CreatePeerConnection(&constraints);
2685 CreateAndSetRemoteOffer(kSdpStringWithoutStreams);
2686
2687 ASSERT_EQ(1u, observer_.remote_streams()->count());
2688 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
2689 EXPECT_EQ(1u, remote_stream->GetAudioTracks().size());
2690 EXPECT_EQ(1u, remote_stream->GetVideoTracks().size());
2691}
2692
2693// This tests that a default MediaStream is not created if the remote session
2694// description doesn't contain any streams but does support MSID.
Taylor Brandstetter7ff17372016-04-01 11:50:39 -07002695TEST_F(PeerConnectionInterfaceTest, SdpWithMsidDontCreatesDefaultStream) {
deadbeefab9b2d12015-10-14 11:33:11 -07002696 FakeConstraints constraints;
2697 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2698 true);
2699 CreatePeerConnection(&constraints);
2700 CreateAndSetRemoteOffer(kSdpStringWithMsidWithoutStreams);
2701 EXPECT_EQ(0u, observer_.remote_streams()->count());
2702}
2703
deadbeefbda7e0b2015-12-08 17:13:40 -08002704// This tests that when setting a new description, the old default tracks are
2705// not destroyed and recreated.
2706// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5250
Stefan Holmer102362b2016-03-18 09:39:07 +01002707TEST_F(PeerConnectionInterfaceTest,
Taylor Brandstetter7ff17372016-04-01 11:50:39 -07002708 DefaultTracksNotDestroyedAndRecreated) {
deadbeefbda7e0b2015-12-08 17:13:40 -08002709 FakeConstraints constraints;
2710 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2711 true);
2712 CreatePeerConnection(&constraints);
2713 CreateAndSetRemoteOffer(kSdpStringWithoutStreamsAudioOnly);
2714
2715 ASSERT_EQ(1u, observer_.remote_streams()->count());
2716 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0);
2717 ASSERT_EQ(1u, remote_stream->GetAudioTracks().size());
2718
2719 // Set the track to "disabled", then set a new description and ensure the
2720 // track is still disabled, which ensures it hasn't been recreated.
2721 remote_stream->GetAudioTracks()[0]->set_enabled(false);
2722 CreateAndSetRemoteOffer(kSdpStringWithoutStreamsAudioOnly);
2723 ASSERT_EQ(1u, remote_stream->GetAudioTracks().size());
2724 EXPECT_FALSE(remote_stream->GetAudioTracks()[0]->enabled());
2725}
2726
deadbeefab9b2d12015-10-14 11:33:11 -07002727// This tests that a default MediaStream is not created if a remote session
2728// description is updated to not have any MediaStreams.
2729TEST_F(PeerConnectionInterfaceTest, VerifyDefaultStreamIsNotCreated) {
2730 FakeConstraints constraints;
2731 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2732 true);
2733 CreatePeerConnection(&constraints);
2734 CreateAndSetRemoteOffer(kSdpStringWithStream1);
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002735 rtc::scoped_refptr<StreamCollection> reference(CreateStreamCollection(1, 1));
deadbeefab9b2d12015-10-14 11:33:11 -07002736 EXPECT_TRUE(
2737 CompareStreamCollections(observer_.remote_streams(), reference.get()));
2738
2739 CreateAndSetRemoteOffer(kSdpStringWithoutStreams);
2740 EXPECT_EQ(0u, observer_.remote_streams()->count());
2741}
2742
2743// This tests that an RtpSender is created when the local description is set
2744// after adding a local stream.
2745// TODO(deadbeef): This test and the one below it need to be updated when
2746// an RtpSender's lifetime isn't determined by when a local description is set.
Taylor Brandstetter7ff17372016-04-01 11:50:39 -07002747TEST_F(PeerConnectionInterfaceTest, LocalDescriptionChanged) {
deadbeefab9b2d12015-10-14 11:33:11 -07002748 FakeConstraints constraints;
2749 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2750 true);
2751 CreatePeerConnection(&constraints);
deadbeefab9b2d12015-10-14 11:33:11 -07002752
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002753 // Create an offer with 1 stream with 2 tracks of each type.
2754 rtc::scoped_refptr<StreamCollection> stream_collection =
2755 CreateStreamCollection(1, 2);
2756 pc_->AddStream(stream_collection->at(0));
2757 std::unique_ptr<SessionDescriptionInterface> offer;
2758 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
2759 EXPECT_TRUE(DoSetLocalDescription(offer.release()));
deadbeefab9b2d12015-10-14 11:33:11 -07002760
deadbeefab9b2d12015-10-14 11:33:11 -07002761 auto senders = pc_->GetSenders();
2762 EXPECT_EQ(4u, senders.size());
2763 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0]));
2764 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0]));
2765 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[1]));
2766 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[1]));
2767
2768 // Remove an audio and video track.
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002769 pc_->RemoveStream(stream_collection->at(0));
2770 stream_collection = CreateStreamCollection(1, 1);
2771 pc_->AddStream(stream_collection->at(0));
2772 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
2773 EXPECT_TRUE(DoSetLocalDescription(offer.release()));
2774
deadbeefab9b2d12015-10-14 11:33:11 -07002775 senders = pc_->GetSenders();
2776 EXPECT_EQ(2u, senders.size());
2777 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0]));
2778 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0]));
2779 EXPECT_FALSE(ContainsSender(senders, kAudioTracks[1]));
2780 EXPECT_FALSE(ContainsSender(senders, kVideoTracks[1]));
2781}
2782
2783// This tests that an RtpSender is created when the local description is set
2784// before adding a local stream.
2785TEST_F(PeerConnectionInterfaceTest,
Taylor Brandstetter7ff17372016-04-01 11:50:39 -07002786 AddLocalStreamAfterLocalDescriptionChanged) {
deadbeefab9b2d12015-10-14 11:33:11 -07002787 FakeConstraints constraints;
2788 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2789 true);
2790 CreatePeerConnection(&constraints);
deadbeefab9b2d12015-10-14 11:33:11 -07002791
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002792 rtc::scoped_refptr<StreamCollection> stream_collection =
2793 CreateStreamCollection(1, 2);
2794 // Add a stream to create the offer, but remove it afterwards.
2795 pc_->AddStream(stream_collection->at(0));
2796 std::unique_ptr<SessionDescriptionInterface> offer;
2797 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
2798 pc_->RemoveStream(stream_collection->at(0));
deadbeefab9b2d12015-10-14 11:33:11 -07002799
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002800 EXPECT_TRUE(DoSetLocalDescription(offer.release()));
deadbeefab9b2d12015-10-14 11:33:11 -07002801 auto senders = pc_->GetSenders();
2802 EXPECT_EQ(0u, senders.size());
2803
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002804 pc_->AddStream(stream_collection->at(0));
deadbeefab9b2d12015-10-14 11:33:11 -07002805 senders = pc_->GetSenders();
2806 EXPECT_EQ(4u, senders.size());
2807 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0]));
2808 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0]));
2809 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[1]));
2810 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[1]));
2811}
2812
2813// This tests that the expected behavior occurs if the SSRC on a local track is
2814// changed when SetLocalDescription is called.
2815TEST_F(PeerConnectionInterfaceTest,
Taylor Brandstetter7ff17372016-04-01 11:50:39 -07002816 ChangeSsrcOnTrackInLocalSessionDescription) {
deadbeefab9b2d12015-10-14 11:33:11 -07002817 FakeConstraints constraints;
2818 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2819 true);
2820 CreatePeerConnection(&constraints);
deadbeefab9b2d12015-10-14 11:33:11 -07002821
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002822 rtc::scoped_refptr<StreamCollection> stream_collection =
2823 CreateStreamCollection(2, 1);
2824 pc_->AddStream(stream_collection->at(0));
2825 std::unique_ptr<SessionDescriptionInterface> offer;
2826 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
2827 // Grab a copy of the offer before it gets passed into the PC.
2828 std::unique_ptr<JsepSessionDescription> modified_offer(
2829 new JsepSessionDescription(JsepSessionDescription::kOffer));
2830 modified_offer->Initialize(offer->description()->Copy(), offer->session_id(),
2831 offer->session_version());
2832 EXPECT_TRUE(DoSetLocalDescription(offer.release()));
deadbeefab9b2d12015-10-14 11:33:11 -07002833
deadbeefab9b2d12015-10-14 11:33:11 -07002834 auto senders = pc_->GetSenders();
2835 EXPECT_EQ(2u, senders.size());
2836 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0]));
2837 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0]));
2838
2839 // Change the ssrc of the audio and video track.
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002840 cricket::MediaContentDescription* desc =
2841 cricket::GetFirstAudioContentDescription(modified_offer->description());
2842 ASSERT_TRUE(desc != NULL);
2843 for (StreamParams& stream : desc->mutable_streams()) {
2844 for (unsigned int& ssrc : stream.ssrcs) {
2845 ++ssrc;
2846 }
2847 }
deadbeefab9b2d12015-10-14 11:33:11 -07002848
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002849 desc =
2850 cricket::GetFirstVideoContentDescription(modified_offer->description());
2851 ASSERT_TRUE(desc != NULL);
2852 for (StreamParams& stream : desc->mutable_streams()) {
2853 for (unsigned int& ssrc : stream.ssrcs) {
2854 ++ssrc;
2855 }
2856 }
2857
2858 EXPECT_TRUE(DoSetLocalDescription(modified_offer.release()));
deadbeefab9b2d12015-10-14 11:33:11 -07002859 senders = pc_->GetSenders();
2860 EXPECT_EQ(2u, senders.size());
2861 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0]));
2862 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0]));
2863 // TODO(deadbeef): Once RtpSenders expose parameters, check that the SSRC
2864 // changed.
2865}
2866
2867// This tests that the expected behavior occurs if a new session description is
2868// set with the same tracks, but on a different MediaStream.
Stefan Holmer55d6e7c2016-03-17 16:26:40 +01002869TEST_F(PeerConnectionInterfaceTest,
Taylor Brandstetter7ff17372016-04-01 11:50:39 -07002870 SignalSameTracksInSeparateMediaStream) {
deadbeefab9b2d12015-10-14 11:33:11 -07002871 FakeConstraints constraints;
2872 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2873 true);
2874 CreatePeerConnection(&constraints);
deadbeefab9b2d12015-10-14 11:33:11 -07002875
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002876 rtc::scoped_refptr<StreamCollection> stream_collection =
2877 CreateStreamCollection(2, 1);
2878 pc_->AddStream(stream_collection->at(0));
2879 std::unique_ptr<SessionDescriptionInterface> offer;
2880 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
2881 EXPECT_TRUE(DoSetLocalDescription(offer.release()));
deadbeefab9b2d12015-10-14 11:33:11 -07002882
deadbeefab9b2d12015-10-14 11:33:11 -07002883 auto senders = pc_->GetSenders();
2884 EXPECT_EQ(2u, senders.size());
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002885 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0], kStreams[0]));
2886 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0], kStreams[0]));
deadbeefab9b2d12015-10-14 11:33:11 -07002887
2888 // Add a new MediaStream but with the same tracks as in the first stream.
2889 rtc::scoped_refptr<webrtc::MediaStreamInterface> stream_1(
2890 webrtc::MediaStream::Create(kStreams[1]));
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002891 stream_1->AddTrack(stream_collection->at(0)->GetVideoTracks()[0]);
2892 stream_1->AddTrack(stream_collection->at(0)->GetAudioTracks()[0]);
deadbeefab9b2d12015-10-14 11:33:11 -07002893 pc_->AddStream(stream_1);
2894
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002895 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
2896 EXPECT_TRUE(DoSetLocalDescription(offer.release()));
deadbeefab9b2d12015-10-14 11:33:11 -07002897
Taylor Brandstetterdc4eb8c2016-05-12 08:14:50 -07002898 auto new_senders = pc_->GetSenders();
2899 // Should be the same senders as before, but with updated stream id.
2900 // Note that this behavior is subject to change in the future.
2901 // We may decide the PC should ignore existing tracks in AddStream.
2902 EXPECT_EQ(senders, new_senders);
2903 EXPECT_TRUE(ContainsSender(new_senders, kAudioTracks[0], kStreams[1]));
2904 EXPECT_TRUE(ContainsSender(new_senders, kVideoTracks[0], kStreams[1]));
deadbeefab9b2d12015-10-14 11:33:11 -07002905}
2906
zhihuang81c3a032016-11-17 12:06:24 -08002907// This tests that PeerConnectionObserver::OnAddTrack is correctly called.
2908TEST_F(PeerConnectionInterfaceTest, OnAddTrackCallback) {
2909 FakeConstraints constraints;
2910 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
2911 true);
2912 CreatePeerConnection(&constraints);
2913 CreateAndSetRemoteOffer(kSdpStringWithStream1AudioTrackOnly);
2914 EXPECT_EQ(observer_.num_added_tracks_, 1);
2915 EXPECT_EQ(observer_.last_added_track_label_, kAudioTracks[0]);
2916
2917 // Create and set the updated remote SDP.
2918 CreateAndSetRemoteOffer(kSdpStringWithStream1);
2919 EXPECT_EQ(observer_.num_added_tracks_, 2);
2920 EXPECT_EQ(observer_.last_added_track_label_, kVideoTracks[0]);
2921}
2922
deadbeefd1a38b52016-12-10 13:15:33 -08002923// Test that when SetConfiguration is called and the configuration is
2924// changing, the next offer causes an ICE restart.
2925TEST_F(PeerConnectionInterfaceTest, SetConfigurationCausingIceRetart) {
2926 PeerConnectionInterface::RTCConfiguration config;
2927 config.type = PeerConnectionInterface::kRelay;
2928 // Need to pass default constraints to prevent disabling of DTLS...
2929 FakeConstraints default_constraints;
2930 CreatePeerConnection(config, &default_constraints);
2931 AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label");
2932
2933 // Do initial offer/answer so there's something to restart.
2934 CreateOfferAsLocalDescription();
2935 CreateAnswerAsRemoteDescription(kSdpStringWithStream1);
2936
2937 // Grab the ufrags.
2938 std::vector<std::string> initial_ufrags = GetUfrags(pc_->local_description());
2939
2940 // Change ICE policy, which should trigger an ICE restart on the next offer.
2941 config.type = PeerConnectionInterface::kAll;
2942 EXPECT_TRUE(pc_->SetConfiguration(config));
2943 CreateOfferAsLocalDescription();
2944
2945 // Grab the new ufrags.
2946 std::vector<std::string> subsequent_ufrags =
2947 GetUfrags(pc_->local_description());
2948
2949 // Sanity check.
2950 EXPECT_EQ(initial_ufrags.size(), subsequent_ufrags.size());
2951 // Check that each ufrag is different.
2952 for (int i = 0; i < static_cast<int>(initial_ufrags.size()); ++i) {
2953 EXPECT_NE(initial_ufrags[i], subsequent_ufrags[i]);
2954 }
2955}
2956
2957// Test that when SetConfiguration is called and the configuration *isn't*
2958// changing, the next offer does *not* cause an ICE restart.
2959TEST_F(PeerConnectionInterfaceTest, SetConfigurationNotCausingIceRetart) {
2960 PeerConnectionInterface::RTCConfiguration config;
2961 config.type = PeerConnectionInterface::kRelay;
2962 // Need to pass default constraints to prevent disabling of DTLS...
2963 FakeConstraints default_constraints;
2964 CreatePeerConnection(config, &default_constraints);
2965 AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label");
2966
2967 // Do initial offer/answer so there's something to restart.
2968 CreateOfferAsLocalDescription();
2969 CreateAnswerAsRemoteDescription(kSdpStringWithStream1);
2970
2971 // Grab the ufrags.
2972 std::vector<std::string> initial_ufrags = GetUfrags(pc_->local_description());
2973
2974 // Call SetConfiguration with a config identical to what the PC was
2975 // constructed with.
2976 EXPECT_TRUE(pc_->SetConfiguration(config));
2977 CreateOfferAsLocalDescription();
2978
2979 // Grab the new ufrags.
2980 std::vector<std::string> subsequent_ufrags =
2981 GetUfrags(pc_->local_description());
2982
2983 EXPECT_EQ(initial_ufrags, subsequent_ufrags);
2984}
2985
2986// Test for a weird corner case scenario:
2987// 1. Audio/video session established.
2988// 2. SetConfiguration changes ICE config; ICE restart needed.
2989// 3. ICE restart initiated by remote peer, but only for one m= section.
2990// 4. Next createOffer should initiate an ICE restart, but only for the other
2991// m= section; it would be pointless to do an ICE restart for the m= section
2992// that was already restarted.
2993TEST_F(PeerConnectionInterfaceTest, SetConfigurationCausingPartialIceRestart) {
2994 PeerConnectionInterface::RTCConfiguration config;
2995 config.type = PeerConnectionInterface::kRelay;
2996 // Need to pass default constraints to prevent disabling of DTLS...
2997 FakeConstraints default_constraints;
2998 CreatePeerConnection(config, &default_constraints);
2999 AddAudioVideoStream(kStreamLabel1, "audio_label", "video_label");
3000
3001 // Do initial offer/answer so there's something to restart.
3002 CreateOfferAsLocalDescription();
3003 CreateAnswerAsRemoteDescription(kSdpStringWithStream1);
3004
3005 // Change ICE policy, which should set the "needs-ice-restart" flag.
3006 config.type = PeerConnectionInterface::kAll;
3007 EXPECT_TRUE(pc_->SetConfiguration(config));
3008
3009 // Do ICE restart for the first m= section, initiated by remote peer.
3010 webrtc::JsepSessionDescription* remote_offer =
3011 new webrtc::JsepSessionDescription(SessionDescriptionInterface::kOffer);
3012 EXPECT_TRUE(remote_offer->Initialize(kSdpStringWithStream1, nullptr));
3013 remote_offer->description()->transport_infos()[0].description.ice_ufrag =
3014 "modified";
3015 EXPECT_TRUE(DoSetRemoteDescription(remote_offer));
3016 CreateAnswerAsLocalDescription();
3017
3018 // Grab the ufrags.
3019 std::vector<std::string> initial_ufrags = GetUfrags(pc_->local_description());
3020 ASSERT_EQ(2, initial_ufrags.size());
3021
3022 // Create offer and grab the new ufrags.
3023 CreateOfferAsLocalDescription();
3024 std::vector<std::string> subsequent_ufrags =
3025 GetUfrags(pc_->local_description());
3026 ASSERT_EQ(2, subsequent_ufrags.size());
3027
3028 // Ensure that only the ufrag for the second m= section changed.
3029 EXPECT_EQ(initial_ufrags[0], subsequent_ufrags[0]);
3030 EXPECT_NE(initial_ufrags[1], subsequent_ufrags[1]);
3031}
3032
deadbeeffe4a8a42016-12-20 17:56:17 -08003033// Tests that the methods to return current/pending descriptions work as
3034// expected at different points in the offer/answer exchange. This test does
3035// one offer/answer exchange as the offerer, then another as the answerer.
3036TEST_F(PeerConnectionInterfaceTest, CurrentAndPendingDescriptions) {
3037 // This disables DTLS so we can apply an answer to ourselves.
3038 CreatePeerConnection();
3039
3040 // Create initial local offer and get SDP (which will also be used as
3041 // answer/pranswer);
3042 std::unique_ptr<SessionDescriptionInterface> offer;
3043 ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
3044 std::string sdp;
3045 EXPECT_TRUE(offer->ToString(&sdp));
3046
3047 // Set local offer.
3048 SessionDescriptionInterface* local_offer = offer.release();
3049 EXPECT_TRUE(DoSetLocalDescription(local_offer));
3050 EXPECT_EQ(local_offer, pc_->pending_local_description());
3051 EXPECT_EQ(nullptr, pc_->pending_remote_description());
3052 EXPECT_EQ(nullptr, pc_->current_local_description());
3053 EXPECT_EQ(nullptr, pc_->current_remote_description());
3054
3055 // Set remote pranswer.
3056 SessionDescriptionInterface* remote_pranswer =
3057 webrtc::CreateSessionDescription(SessionDescriptionInterface::kPrAnswer,
3058 sdp, nullptr);
3059 EXPECT_TRUE(DoSetRemoteDescription(remote_pranswer));
3060 EXPECT_EQ(local_offer, pc_->pending_local_description());
3061 EXPECT_EQ(remote_pranswer, pc_->pending_remote_description());
3062 EXPECT_EQ(nullptr, pc_->current_local_description());
3063 EXPECT_EQ(nullptr, pc_->current_remote_description());
3064
3065 // Set remote answer.
3066 SessionDescriptionInterface* remote_answer = webrtc::CreateSessionDescription(
3067 SessionDescriptionInterface::kAnswer, sdp, nullptr);
3068 EXPECT_TRUE(DoSetRemoteDescription(remote_answer));
3069 EXPECT_EQ(nullptr, pc_->pending_local_description());
3070 EXPECT_EQ(nullptr, pc_->pending_remote_description());
3071 EXPECT_EQ(local_offer, pc_->current_local_description());
3072 EXPECT_EQ(remote_answer, pc_->current_remote_description());
3073
3074 // Set remote offer.
3075 SessionDescriptionInterface* remote_offer = webrtc::CreateSessionDescription(
3076 SessionDescriptionInterface::kOffer, sdp, nullptr);
3077 EXPECT_TRUE(DoSetRemoteDescription(remote_offer));
3078 EXPECT_EQ(remote_offer, pc_->pending_remote_description());
3079 EXPECT_EQ(nullptr, pc_->pending_local_description());
3080 EXPECT_EQ(local_offer, pc_->current_local_description());
3081 EXPECT_EQ(remote_answer, pc_->current_remote_description());
3082
3083 // Set local pranswer.
3084 SessionDescriptionInterface* local_pranswer =
3085 webrtc::CreateSessionDescription(SessionDescriptionInterface::kPrAnswer,
3086 sdp, nullptr);
3087 EXPECT_TRUE(DoSetLocalDescription(local_pranswer));
3088 EXPECT_EQ(remote_offer, pc_->pending_remote_description());
3089 EXPECT_EQ(local_pranswer, pc_->pending_local_description());
3090 EXPECT_EQ(local_offer, pc_->current_local_description());
3091 EXPECT_EQ(remote_answer, pc_->current_remote_description());
3092
3093 // Set local answer.
3094 SessionDescriptionInterface* local_answer = webrtc::CreateSessionDescription(
3095 SessionDescriptionInterface::kAnswer, sdp, nullptr);
3096 EXPECT_TRUE(DoSetLocalDescription(local_answer));
3097 EXPECT_EQ(nullptr, pc_->pending_remote_description());
3098 EXPECT_EQ(nullptr, pc_->pending_local_description());
3099 EXPECT_EQ(remote_offer, pc_->current_remote_description());
3100 EXPECT_EQ(local_answer, pc_->current_local_description());
3101}
3102
nisse51542be2016-02-12 02:27:06 -08003103class PeerConnectionMediaConfigTest : public testing::Test {
3104 protected:
3105 void SetUp() override {
nisseaf510af2016-03-21 08:20:42 -07003106 pcf_ = new rtc::RefCountedObject<PeerConnectionFactoryForTest>();
nisse51542be2016-02-12 02:27:06 -08003107 pcf_->Initialize();
3108 }
3109 const cricket::MediaConfig& TestCreatePeerConnection(
3110 const PeerConnectionInterface::RTCConfiguration& config,
3111 const MediaConstraintsInterface *constraints) {
3112 pcf_->create_media_controller_called_ = false;
3113
zhihuang9763d562016-08-05 11:14:50 -07003114 rtc::scoped_refptr<PeerConnectionInterface> pc(pcf_->CreatePeerConnection(
3115 config, constraints, nullptr, nullptr, &observer_));
nisse51542be2016-02-12 02:27:06 -08003116 EXPECT_TRUE(pc.get());
3117 EXPECT_TRUE(pcf_->create_media_controller_called_);
3118 return pcf_->create_media_controller_config_;
3119 }
3120
zhihuang9763d562016-08-05 11:14:50 -07003121 rtc::scoped_refptr<PeerConnectionFactoryForTest> pcf_;
nisse51542be2016-02-12 02:27:06 -08003122 MockPeerConnectionObserver observer_;
3123};
3124
3125// This test verifies the default behaviour with no constraints and a
3126// default RTCConfiguration.
3127TEST_F(PeerConnectionMediaConfigTest, TestDefaults) {
3128 PeerConnectionInterface::RTCConfiguration config;
3129 FakeConstraints constraints;
3130
3131 const cricket::MediaConfig& media_config =
3132 TestCreatePeerConnection(config, &constraints);
3133
3134 EXPECT_FALSE(media_config.enable_dscp);
nisse0db023a2016-03-01 04:29:59 -08003135 EXPECT_TRUE(media_config.video.enable_cpu_overuse_detection);
3136 EXPECT_FALSE(media_config.video.disable_prerenderer_smoothing);
3137 EXPECT_FALSE(media_config.video.suspend_below_min_bitrate);
nisse51542be2016-02-12 02:27:06 -08003138}
3139
3140// This test verifies the DSCP constraint is recognized and passed to
3141// the CreateMediaController call.
3142TEST_F(PeerConnectionMediaConfigTest, TestDscpConstraintTrue) {
3143 PeerConnectionInterface::RTCConfiguration config;
3144 FakeConstraints constraints;
3145
3146 constraints.AddOptional(webrtc::MediaConstraintsInterface::kEnableDscp, true);
3147 const cricket::MediaConfig& media_config =
3148 TestCreatePeerConnection(config, &constraints);
3149
3150 EXPECT_TRUE(media_config.enable_dscp);
3151}
3152
3153// This test verifies the cpu overuse detection constraint is
3154// recognized and passed to the CreateMediaController call.
3155TEST_F(PeerConnectionMediaConfigTest, TestCpuOveruseConstraintFalse) {
3156 PeerConnectionInterface::RTCConfiguration config;
3157 FakeConstraints constraints;
3158
3159 constraints.AddOptional(
3160 webrtc::MediaConstraintsInterface::kCpuOveruseDetection, false);
3161 const cricket::MediaConfig media_config =
3162 TestCreatePeerConnection(config, &constraints);
3163
nisse0db023a2016-03-01 04:29:59 -08003164 EXPECT_FALSE(media_config.video.enable_cpu_overuse_detection);
nisse51542be2016-02-12 02:27:06 -08003165}
3166
3167// This test verifies that the disable_prerenderer_smoothing flag is
3168// propagated from RTCConfiguration to the CreateMediaController call.
3169TEST_F(PeerConnectionMediaConfigTest, TestDisablePrerendererSmoothingTrue) {
3170 PeerConnectionInterface::RTCConfiguration config;
3171 FakeConstraints constraints;
3172
Niels Möller71bdda02016-03-31 12:59:59 +02003173 config.set_prerenderer_smoothing(false);
nisse51542be2016-02-12 02:27:06 -08003174 const cricket::MediaConfig& media_config =
3175 TestCreatePeerConnection(config, &constraints);
3176
nisse0db023a2016-03-01 04:29:59 -08003177 EXPECT_TRUE(media_config.video.disable_prerenderer_smoothing);
3178}
3179
3180// This test verifies the suspend below min bitrate constraint is
3181// recognized and passed to the CreateMediaController call.
3182TEST_F(PeerConnectionMediaConfigTest,
3183 TestSuspendBelowMinBitrateConstraintTrue) {
3184 PeerConnectionInterface::RTCConfiguration config;
3185 FakeConstraints constraints;
3186
3187 constraints.AddOptional(
3188 webrtc::MediaConstraintsInterface::kEnableVideoSuspendBelowMinBitrate,
3189 true);
3190 const cricket::MediaConfig media_config =
3191 TestCreatePeerConnection(config, &constraints);
3192
3193 EXPECT_TRUE(media_config.video.suspend_below_min_bitrate);
nisse51542be2016-02-12 02:27:06 -08003194}
3195
deadbeefab9b2d12015-10-14 11:33:11 -07003196// The following tests verify that session options are created correctly.
deadbeefc80741f2015-10-22 13:14:45 -07003197// TODO(deadbeef): Convert these tests to be more end-to-end. Instead of
3198// "verify options are converted correctly", should be "pass options into
3199// CreateOffer and verify the correct offer is produced."
deadbeefab9b2d12015-10-14 11:33:11 -07003200
3201TEST(CreateSessionOptionsTest, GetOptionsForOfferWithInvalidAudioOption) {
3202 RTCOfferAnswerOptions rtc_options;
3203 rtc_options.offer_to_receive_audio = RTCOfferAnswerOptions::kUndefined - 1;
3204
3205 cricket::MediaSessionOptions options;
htaaac2dea2016-03-10 13:35:55 -08003206 EXPECT_FALSE(ExtractMediaSessionOptions(rtc_options, true, &options));
deadbeefab9b2d12015-10-14 11:33:11 -07003207
3208 rtc_options.offer_to_receive_audio =
3209 RTCOfferAnswerOptions::kMaxOfferToReceiveMedia + 1;
htaaac2dea2016-03-10 13:35:55 -08003210 EXPECT_FALSE(ExtractMediaSessionOptions(rtc_options, true, &options));
deadbeefab9b2d12015-10-14 11:33:11 -07003211}
3212
3213TEST(CreateSessionOptionsTest, GetOptionsForOfferWithInvalidVideoOption) {
3214 RTCOfferAnswerOptions rtc_options;
3215 rtc_options.offer_to_receive_video = RTCOfferAnswerOptions::kUndefined - 1;
3216
3217 cricket::MediaSessionOptions options;
htaaac2dea2016-03-10 13:35:55 -08003218 EXPECT_FALSE(ExtractMediaSessionOptions(rtc_options, true, &options));
deadbeefab9b2d12015-10-14 11:33:11 -07003219
3220 rtc_options.offer_to_receive_video =
3221 RTCOfferAnswerOptions::kMaxOfferToReceiveMedia + 1;
htaaac2dea2016-03-10 13:35:55 -08003222 EXPECT_FALSE(ExtractMediaSessionOptions(rtc_options, true, &options));
deadbeefab9b2d12015-10-14 11:33:11 -07003223}
3224
3225// Test that a MediaSessionOptions is created for an offer if
deadbeefc80741f2015-10-22 13:14:45 -07003226// OfferToReceiveAudio and OfferToReceiveVideo options are set.
deadbeefab9b2d12015-10-14 11:33:11 -07003227TEST(CreateSessionOptionsTest, GetMediaSessionOptionsForOfferWithAudioVideo) {
3228 RTCOfferAnswerOptions rtc_options;
3229 rtc_options.offer_to_receive_audio = 1;
3230 rtc_options.offer_to_receive_video = 1;
3231
3232 cricket::MediaSessionOptions options;
htaaac2dea2016-03-10 13:35:55 -08003233 EXPECT_TRUE(ExtractMediaSessionOptions(rtc_options, true, &options));
deadbeefab9b2d12015-10-14 11:33:11 -07003234 EXPECT_TRUE(options.has_audio());
3235 EXPECT_TRUE(options.has_video());
3236 EXPECT_TRUE(options.bundle_enabled);
3237}
3238
3239// Test that a correct MediaSessionOptions is created for an offer if
deadbeefc80741f2015-10-22 13:14:45 -07003240// OfferToReceiveAudio is set.
deadbeefab9b2d12015-10-14 11:33:11 -07003241TEST(CreateSessionOptionsTest, GetMediaSessionOptionsForOfferWithAudio) {
3242 RTCOfferAnswerOptions rtc_options;
3243 rtc_options.offer_to_receive_audio = 1;
3244
3245 cricket::MediaSessionOptions options;
htaaac2dea2016-03-10 13:35:55 -08003246 EXPECT_TRUE(ExtractMediaSessionOptions(rtc_options, true, &options));
deadbeefab9b2d12015-10-14 11:33:11 -07003247 EXPECT_TRUE(options.has_audio());
3248 EXPECT_FALSE(options.has_video());
3249 EXPECT_TRUE(options.bundle_enabled);
3250}
3251
3252// Test that a correct MediaSessionOptions is created for an offer if
deadbeefc80741f2015-10-22 13:14:45 -07003253// the default OfferOptions are used.
deadbeefab9b2d12015-10-14 11:33:11 -07003254TEST(CreateSessionOptionsTest, GetDefaultMediaSessionOptionsForOffer) {
3255 RTCOfferAnswerOptions rtc_options;
3256
3257 cricket::MediaSessionOptions options;
deadbeef0ed85b22016-02-23 17:24:52 -08003258 options.transport_options["audio"] = cricket::TransportOptions();
3259 options.transport_options["video"] = cricket::TransportOptions();
htaaac2dea2016-03-10 13:35:55 -08003260 EXPECT_TRUE(ExtractMediaSessionOptions(rtc_options, true, &options));
deadbeefc80741f2015-10-22 13:14:45 -07003261 EXPECT_TRUE(options.has_audio());
deadbeefab9b2d12015-10-14 11:33:11 -07003262 EXPECT_FALSE(options.has_video());
deadbeefc80741f2015-10-22 13:14:45 -07003263 EXPECT_TRUE(options.bundle_enabled);
deadbeefab9b2d12015-10-14 11:33:11 -07003264 EXPECT_TRUE(options.vad_enabled);
deadbeef0ed85b22016-02-23 17:24:52 -08003265 EXPECT_FALSE(options.transport_options["audio"].ice_restart);
3266 EXPECT_FALSE(options.transport_options["video"].ice_restart);
deadbeefab9b2d12015-10-14 11:33:11 -07003267}
3268
3269// Test that a correct MediaSessionOptions is created for an offer if
deadbeefc80741f2015-10-22 13:14:45 -07003270// OfferToReceiveVideo is set.
deadbeefab9b2d12015-10-14 11:33:11 -07003271TEST(CreateSessionOptionsTest, GetMediaSessionOptionsForOfferWithVideo) {
3272 RTCOfferAnswerOptions rtc_options;
3273 rtc_options.offer_to_receive_audio = 0;
3274 rtc_options.offer_to_receive_video = 1;
3275
3276 cricket::MediaSessionOptions options;
htaaac2dea2016-03-10 13:35:55 -08003277 EXPECT_TRUE(ExtractMediaSessionOptions(rtc_options, true, &options));
deadbeefab9b2d12015-10-14 11:33:11 -07003278 EXPECT_FALSE(options.has_audio());
3279 EXPECT_TRUE(options.has_video());
3280 EXPECT_TRUE(options.bundle_enabled);
3281}
3282
3283// Test that a correct MediaSessionOptions is created for an offer if
3284// UseRtpMux is set to false.
3285TEST(CreateSessionOptionsTest,
3286 GetMediaSessionOptionsForOfferWithBundleDisabled) {
3287 RTCOfferAnswerOptions rtc_options;
3288 rtc_options.offer_to_receive_audio = 1;
3289 rtc_options.offer_to_receive_video = 1;
3290 rtc_options.use_rtp_mux = false;
3291
3292 cricket::MediaSessionOptions options;
htaaac2dea2016-03-10 13:35:55 -08003293 EXPECT_TRUE(ExtractMediaSessionOptions(rtc_options, true, &options));
deadbeefab9b2d12015-10-14 11:33:11 -07003294 EXPECT_TRUE(options.has_audio());
3295 EXPECT_TRUE(options.has_video());
3296 EXPECT_FALSE(options.bundle_enabled);
3297}
3298
3299// Test that a correct MediaSessionOptions is created to restart ice if
3300// IceRestart is set. It also tests that subsequent MediaSessionOptions don't
Taylor Brandstetterf475d362016-01-08 15:35:57 -08003301// have |audio_transport_options.ice_restart| etc. set.
deadbeefab9b2d12015-10-14 11:33:11 -07003302TEST(CreateSessionOptionsTest, GetMediaSessionOptionsForOfferWithIceRestart) {
3303 RTCOfferAnswerOptions rtc_options;
3304 rtc_options.ice_restart = true;
3305
3306 cricket::MediaSessionOptions options;
deadbeef0ed85b22016-02-23 17:24:52 -08003307 options.transport_options["audio"] = cricket::TransportOptions();
3308 options.transport_options["video"] = cricket::TransportOptions();
htaaac2dea2016-03-10 13:35:55 -08003309 EXPECT_TRUE(ExtractMediaSessionOptions(rtc_options, true, &options));
deadbeef0ed85b22016-02-23 17:24:52 -08003310 EXPECT_TRUE(options.transport_options["audio"].ice_restart);
3311 EXPECT_TRUE(options.transport_options["video"].ice_restart);
deadbeefab9b2d12015-10-14 11:33:11 -07003312
3313 rtc_options = RTCOfferAnswerOptions();
htaaac2dea2016-03-10 13:35:55 -08003314 EXPECT_TRUE(ExtractMediaSessionOptions(rtc_options, true, &options));
deadbeef0ed85b22016-02-23 17:24:52 -08003315 EXPECT_FALSE(options.transport_options["audio"].ice_restart);
3316 EXPECT_FALSE(options.transport_options["video"].ice_restart);
deadbeefab9b2d12015-10-14 11:33:11 -07003317}
3318
3319// Test that the MediaConstraints in an answer don't affect if audio and video
3320// is offered in an offer but that if kOfferToReceiveAudio or
3321// kOfferToReceiveVideo constraints are true in an offer, the media type will be
3322// included in subsequent answers.
3323TEST(CreateSessionOptionsTest, MediaConstraintsInAnswer) {
3324 FakeConstraints answer_c;
3325 answer_c.SetMandatoryReceiveAudio(true);
3326 answer_c.SetMandatoryReceiveVideo(true);
3327
3328 cricket::MediaSessionOptions answer_options;
3329 EXPECT_TRUE(ParseConstraintsForAnswer(&answer_c, &answer_options));
3330 EXPECT_TRUE(answer_options.has_audio());
3331 EXPECT_TRUE(answer_options.has_video());
3332
deadbeefc80741f2015-10-22 13:14:45 -07003333 RTCOfferAnswerOptions rtc_offer_options;
deadbeefab9b2d12015-10-14 11:33:11 -07003334
3335 cricket::MediaSessionOptions offer_options;
htaaac2dea2016-03-10 13:35:55 -08003336 EXPECT_TRUE(
3337 ExtractMediaSessionOptions(rtc_offer_options, false, &offer_options));
deadbeefc80741f2015-10-22 13:14:45 -07003338 EXPECT_TRUE(offer_options.has_audio());
htaaac2dea2016-03-10 13:35:55 -08003339 EXPECT_TRUE(offer_options.has_video());
deadbeefab9b2d12015-10-14 11:33:11 -07003340
deadbeefc80741f2015-10-22 13:14:45 -07003341 RTCOfferAnswerOptions updated_rtc_offer_options;
3342 updated_rtc_offer_options.offer_to_receive_audio = 1;
3343 updated_rtc_offer_options.offer_to_receive_video = 1;
deadbeefab9b2d12015-10-14 11:33:11 -07003344
3345 cricket::MediaSessionOptions updated_offer_options;
htaaac2dea2016-03-10 13:35:55 -08003346 EXPECT_TRUE(ExtractMediaSessionOptions(updated_rtc_offer_options, false,
htaa2a49d92016-03-04 02:51:39 -08003347 &updated_offer_options));
deadbeefab9b2d12015-10-14 11:33:11 -07003348 EXPECT_TRUE(updated_offer_options.has_audio());
3349 EXPECT_TRUE(updated_offer_options.has_video());
3350
3351 // Since an offer has been created with both audio and video, subsequent
3352 // offers and answers should contain both audio and video.
3353 // Answers will only contain the media types that exist in the offer
3354 // regardless of the value of |updated_answer_options.has_audio| and
3355 // |updated_answer_options.has_video|.
3356 FakeConstraints updated_answer_c;
3357 answer_c.SetMandatoryReceiveAudio(false);
3358 answer_c.SetMandatoryReceiveVideo(false);
3359
3360 cricket::MediaSessionOptions updated_answer_options;
3361 EXPECT_TRUE(
3362 ParseConstraintsForAnswer(&updated_answer_c, &updated_answer_options));
3363 EXPECT_TRUE(updated_answer_options.has_audio());
3364 EXPECT_TRUE(updated_answer_options.has_video());
deadbeefab9b2d12015-10-14 11:33:11 -07003365}
deadbeef3edec7c2016-12-10 11:44:26 -08003366
deadbeef293e9262017-01-11 12:28:30 -08003367TEST(RTCErrorTypeTest, OstreamOperator) {
deadbeef3edec7c2016-12-10 11:44:26 -08003368 std::ostringstream oss;
deadbeef293e9262017-01-11 12:28:30 -08003369 oss << webrtc::RTCErrorType::NONE << ' '
3370 << webrtc::RTCErrorType::INVALID_PARAMETER << ' '
3371 << webrtc::RTCErrorType::INTERNAL_ERROR;
deadbeef3edec7c2016-12-10 11:44:26 -08003372 EXPECT_EQ("NONE INVALID_PARAMETER INTERNAL_ERROR", oss.str());
3373}
deadbeef293e9262017-01-11 12:28:30 -08003374
3375// Tests a few random fields being different.
3376TEST(RTCConfigurationTest, ComparisonOperators) {
3377 PeerConnectionInterface::RTCConfiguration a;
3378 PeerConnectionInterface::RTCConfiguration b;
3379 EXPECT_EQ(a, b);
3380
3381 PeerConnectionInterface::RTCConfiguration c;
3382 c.servers.push_back(PeerConnectionInterface::IceServer());
3383 EXPECT_NE(a, c);
3384
3385 PeerConnectionInterface::RTCConfiguration d;
3386 d.type = PeerConnectionInterface::kRelay;
3387 EXPECT_NE(a, d);
3388
3389 PeerConnectionInterface::RTCConfiguration e;
3390 e.audio_jitter_buffer_max_packets = 5;
3391 EXPECT_NE(a, e);
3392
3393 PeerConnectionInterface::RTCConfiguration f;
3394 f.ice_connection_receiving_timeout = 1337;
3395 EXPECT_NE(a, f);
3396
3397 PeerConnectionInterface::RTCConfiguration g;
3398 g.disable_ipv6 = true;
3399 EXPECT_NE(a, g);
3400
3401 PeerConnectionInterface::RTCConfiguration h(
3402 PeerConnectionInterface::RTCConfigurationType::kAggressive);
3403 EXPECT_NE(a, h);
3404}