3
* Copyright 2011, Google Inc.
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions are met:
8
* 1. Redistributions of source code must retain the above copyright notice,
9
* this list of conditions and the following disclaimer.
10
* 2. Redistributions in binary form must reproduce the above copyright notice,
11
* this list of conditions and the following disclaimer in the documentation
12
* and/or other materials provided with the distribution.
13
* 3. The name of the author may not be used to endorse or promote products
14
* derived from this software without specific prior written permission.
16
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
#include "talk/app/webrtc/roapmessages.h"
31
#include "talk/app/webrtc/roapsession.h"
32
#include "talk/base/gunit.h"
33
#include "talk/base/logging.h"
34
#include "talk/base/scoped_ptr.h"
36
using webrtc::RoapMessageBase;
37
using webrtc::RoapSession;
38
using webrtc::RoapAnswer;
39
using webrtc::RoapOffer;
41
// Reference sdp string
42
static const char kSdpDescription1[] =
43
"m=fake content 1\r\n"
44
"m=fake content 2\r\n";
46
static const char kSdpDescription2[] =
47
"m=fake content 3\r\n"
48
"m=fake content 4\r\n";
50
TEST(RoapSessionTest, OfferAnswer) {
51
RoapSession roap_session1;
52
RoapSession roap_session2;
54
std::string offer_message = roap_session1.CreateOffer(kSdpDescription1);
56
// Check that it is valid to send to another peer.
57
EXPECT_EQ(RoapSession::kOffer, roap_session2.Parse(offer_message));
58
std::string received_offer(roap_session2.RemoteDescription());
60
EXPECT_FALSE(received_offer.empty());
61
EXPECT_EQ(kSdpDescription1, received_offer);
63
std::string answer_message = roap_session2.CreateAnswer(kSdpDescription2);
65
EXPECT_EQ(RoapSession::kAnswer, roap_session1.Parse(answer_message));
66
std::string received_answer(roap_session1.RemoteDescription());
68
EXPECT_EQ(kSdpDescription2, received_answer);
69
EXPECT_NE(received_offer, received_answer);
72
TEST(RoapSessionTest, InvalidInitialization) {
73
RoapSession roap_session1;
74
RoapSession roap_session2;
76
std::string offer_message1 = roap_session1.CreateOffer(kSdpDescription1);
77
std::string offer_message2 = roap_session2.CreateOffer(kSdpDescription2);
79
// It is an error to receive an initial offer if you have sent an
81
EXPECT_EQ(RoapSession::kInvalidMessage,
82
roap_session1.Parse(offer_message2));
84
EXPECT_EQ(RoapSession::kInvalidMessage,
85
roap_session2.Parse(offer_message1));
88
TEST(RoapSessionTest, Glare) {
89
RoapSession roap_session1;
90
RoapSession roap_session2;
92
// Setup. Need to exchange an offer and an answer in order to test for glare.
93
std::string offer_message1 = roap_session1.CreateOffer(kSdpDescription1);
95
roap_session2.Parse(offer_message1);
96
std::string answer_message2 = roap_session2.CreateAnswer(kSdpDescription2);
97
roap_session1.Parse(answer_message2);
99
// Ok- we should now have all we need. Create a glare condition by
100
// updating the offer simultaneously.
101
offer_message1 = roap_session1.CreateOffer(kSdpDescription2);
102
std::string offer_message2 = roap_session2.CreateOffer(kSdpDescription1);
105
(RoapSession::kOffer == roap_session1.Parse(offer_message2) &&
106
RoapSession::kParseConflict == roap_session2.Parse(offer_message1)) ||
107
(RoapSession::kOffer == roap_session2.Parse(offer_message1) &&
108
RoapSession::kParseConflict == roap_session1.Parse(offer_message2)));
111
// Test Glare resolution by setting different TieBreakers.
112
TEST(RoapSessionTest, TieBreaker) {
113
RoapSession roap_session1;
114
RoapSession roap_session2;
117
std::string offer_message1 = roap_session1.CreateOffer(kSdpDescription1);
119
EXPECT_EQ(RoapSession::kOffer, roap_session2.Parse(offer_message1));
120
std::string received_offer(roap_session2.RemoteDescription());
121
std::string answer_message2 = roap_session2.CreateAnswer(kSdpDescription2);
123
EXPECT_EQ(RoapSession::kAnswer, roap_session1.Parse(answer_message2));
125
// Ok- we should now have all we need. Create a double conflict condition.
126
offer_message1 = roap_session1.CreateOffer(kSdpDescription2);
127
RoapMessageBase message_base;
128
EXPECT_TRUE(message_base.Parse(offer_message1));
129
RoapOffer message_offer(message_base);
130
EXPECT_TRUE(message_offer.Parse());
131
RoapOffer double_conflict_offer(message_offer.answer_session_id(),
132
message_offer.offer_session_id(),
135
message_offer.tie_breaker(),
137
EXPECT_EQ(RoapSession::kParseDoubleConflict,
138
roap_session1.Parse(double_conflict_offer.Serialize()));
140
// After a double conflict both offers must be abandoned and a new offer
141
// created. Recreate the sent offer.
142
offer_message1 = roap_session1.CreateOffer(kSdpDescription2);
143
EXPECT_TRUE(message_base.Parse(offer_message1));
144
RoapOffer message_offer2(message_base);
146
RoapOffer losing_offer(message_offer2.answer_session_id(),
147
message_offer2.offer_session_id(),
149
message_offer2.seq(),
152
EXPECT_EQ(RoapSession::kParseConflict,
153
roap_session1.Parse(losing_offer.Serialize()));
155
RoapOffer winning_offer(message_offer2.answer_session_id(),
156
message_offer2.offer_session_id(),
158
message_offer2.seq(),
161
EXPECT_EQ(RoapSession::kOffer,
162
roap_session1.Parse(winning_offer.Serialize()));
165
TEST(RoapSessionTest, SequenceNumberOnOffer) {
166
RoapSession roap_session1;
167
RoapSession roap_session2;
169
std::string offer_message = roap_session1.CreateOffer(kSdpDescription1);
170
EXPECT_EQ(RoapSession::kOffer, roap_session2.Parse(offer_message));
172
// Invalid since we have already received the same message.
173
EXPECT_EQ(RoapSession::kInvalidMessage, roap_session2.Parse(offer_message));
175
RoapMessageBase message_base;
176
EXPECT_TRUE(message_base.Parse(offer_message));
177
RoapOffer message_offer(message_base);
178
EXPECT_TRUE(message_offer.Parse());
179
// Create a new offer with higher sequence number.
180
RoapOffer new_offer(message_offer.offer_session_id(),
181
message_offer.answer_session_id(),
182
message_offer.session_token(),
183
message_offer.seq()+1,
187
EXPECT_EQ(RoapSession::kOffer, roap_session2.Parse(new_offer.Serialize()));
190
TEST(RoapSessionTest, SequenceNumberOnOfferInGlare) {
191
RoapSession roap_session1;
192
RoapSession roap_session2;
194
// Setup. Need to exchange an offer and an answer in order to test for glare.
195
std::string offer_message1 = roap_session1.CreateOffer(kSdpDescription1);
197
roap_session2.Parse(offer_message1);
198
std::string answer_message2 = roap_session2.CreateAnswer(kSdpDescription2);
199
roap_session1.Parse(answer_message2);
201
// Ok- we should now have all we need. Create a glare condition by
202
// updating the offers simultaneously.
203
offer_message1 = roap_session1.CreateOffer(kSdpDescription2);
204
std::string offer_message2 = roap_session2.CreateOffer(kSdpDescription1);
206
RoapMessageBase message_base;
207
EXPECT_TRUE(message_base.Parse(offer_message1));
208
RoapOffer message_offer(message_base);
209
EXPECT_TRUE(message_offer.Parse());
210
// Create an offer with lower sequence number.
211
RoapOffer bad_offer(message_offer.offer_session_id(),
212
message_offer.answer_session_id(),
213
message_offer.session_token(),
214
message_offer.seq()-1,
218
EXPECT_EQ(RoapSession::kInvalidMessage,
219
roap_session2.Parse(bad_offer.Serialize()));
221
// Test that we accept offers with higher sequence number in glare.
222
RoapOffer god_offer(message_offer.offer_session_id(),
223
message_offer.answer_session_id(),
224
message_offer.session_token(),
225
message_offer.seq()+1,
229
EXPECT_EQ(RoapSession::kOffer,
230
roap_session2.Parse(god_offer.Serialize()));
234
TEST(RoapSessionTest, SequenceNumberOnAnswer) {
235
RoapSession roap_session1;
236
RoapSession roap_session2;
238
std::string offer_message = roap_session1.CreateOffer(kSdpDescription1);
240
EXPECT_EQ(RoapSession::kOffer, roap_session2.Parse(offer_message));
241
std::string answer_message = roap_session2.CreateAnswer(kSdpDescription2);
243
RoapMessageBase message_base;
244
EXPECT_TRUE(message_base.Parse(offer_message));
245
RoapAnswer message_answer(message_base);
246
EXPECT_TRUE(message_answer.Parse());
248
// Create an answer with higher sequence number than the offer.
249
RoapAnswer bad_answer(message_answer.offer_session_id(),
250
message_answer.answer_session_id(),
251
message_answer.session_token(),
252
message_answer.response_token(),
253
message_answer.seq()+1,
256
EXPECT_EQ(RoapSession::kInvalidMessage,
257
roap_session1.Parse(bad_answer.Serialize()));
259
RoapAnswer god_answer(message_answer.offer_session_id(),
260
message_answer.answer_session_id(),
261
message_answer.session_token(),
262
message_answer.response_token(),
263
message_answer.seq(),
266
EXPECT_EQ(RoapSession::kAnswer, roap_session1.Parse(god_answer.Serialize()));
269
TEST(RoapSessionTest, ShutDownOk) {
270
RoapSession roap_session1;
271
std::string shutdown = roap_session1.CreateShutDown();
273
RoapSession roap_session2;
274
EXPECT_EQ(RoapSession::kShutDown, roap_session2.Parse(shutdown));
276
std::string ok_message = roap_session2.CreateOk();
277
EXPECT_EQ(RoapSession::kOk, roap_session1.Parse(ok_message));
280
TEST(RoapSessionTest, ErrorMessageCreation) {
281
RoapSession roap_session1;
282
RoapSession roap_session2;
284
std::string message = roap_session1.CreateErrorMessage(webrtc::kNoMatch);
285
EXPECT_EQ(RoapSession::kError, roap_session2.Parse(message));
286
EXPECT_EQ(webrtc::kNoMatch, roap_session2.RemoteError());
288
message = roap_session1.CreateErrorMessage(webrtc::kTimeout);
289
EXPECT_EQ(RoapSession::kError, roap_session2.Parse(message));
290
EXPECT_EQ(webrtc::kTimeout, roap_session2.RemoteError());
292
message = roap_session1.CreateErrorMessage(webrtc::kRefused);
293
EXPECT_EQ(RoapSession::kError, roap_session2.Parse(message));
294
EXPECT_EQ(webrtc::kRefused, roap_session2.RemoteError());
296
message = roap_session1.CreateErrorMessage(webrtc::kConflict);
297
EXPECT_EQ(RoapSession::kError, roap_session2.Parse(message));
298
EXPECT_EQ(webrtc::kConflict, roap_session2.RemoteError());
300
message = roap_session1.CreateErrorMessage(webrtc::kDoubleConflict);
301
EXPECT_EQ(RoapSession::kError, roap_session2.Parse(message));
302
EXPECT_EQ(webrtc::kDoubleConflict, roap_session2.RemoteError());
304
message = roap_session1.CreateErrorMessage(webrtc::kFailed);
305
EXPECT_EQ(RoapSession::kError, roap_session2.Parse(message));
306
EXPECT_EQ(webrtc::kFailed, roap_session2.RemoteError());