Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(340)

Side by Side Diff: webrtc/api/quicdatatransport_unittest.cc

Issue 2514883002: Create //webrtc/api:libjingle_peerconnection_api + refactorings. (Closed)
Patch Set: Rebase Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/api/quicdatatransport.cc ('k') | webrtc/api/remoteaudiosource.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright 2016 The WebRTC project authors. All Rights Reserved.
3 *
4 * 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.
9 */
10
11 #include "webrtc/api/quicdatatransport.h"
12
13 #include <memory>
14 #include <set>
15 #include <string>
16 #include <unordered_map>
17 #include <vector>
18
19 #include "webrtc/api/quicdatachannel.h"
20 #include "webrtc/base/bytebuffer.h"
21 #include "webrtc/base/gunit.h"
22 #include "webrtc/p2p/base/faketransportcontroller.h"
23 #include "webrtc/p2p/quic/quictransportchannel.h"
24 #include "webrtc/p2p/quic/reliablequicstream.h"
25
26 using webrtc::DataBuffer;
27 using webrtc::DataChannelInit;
28 using webrtc::DataChannelInterface;
29 using webrtc::DataChannelObserver;
30 using webrtc::QuicDataChannel;
31 using webrtc::QuicDataTransport;
32 using cricket::FakeTransportChannel;
33 using cricket::FakeTransportController;
34 using cricket::QuicTransportChannel;
35 using cricket::ReliableQuicStream;
36
37 namespace {
38
39 // Timeout for asynchronous operations.
40 static const int kTimeoutMs = 1000; // milliseconds
41 static const char kTransportName[] = "data";
42
43 // FakeObserver receives messages from the data channel.
44 class FakeObserver : public DataChannelObserver {
45 public:
46 FakeObserver() {}
47
48 void OnStateChange() override {}
49
50 void OnBufferedAmountChange(uint64_t previous_amount) override {}
51
52 void OnMessage(const webrtc::DataBuffer& buffer) override {
53 messages_.push_back(std::string(buffer.data.data<char>(), buffer.size()));
54 }
55
56 const std::vector<std::string>& messages() const { return messages_; }
57
58 size_t messages_received() const { return messages_.size(); }
59
60 private:
61 std::vector<std::string> messages_;
62 };
63
64 // A peer who uses a QUIC transport channel and fake ICE transport channel to
65 // send or receive data.
66 class QuicDataTransportPeer {
67 public:
68 QuicDataTransportPeer()
69 : fake_transport_controller_(new FakeTransportController()),
70 quic_data_transport_(rtc::Thread::Current(),
71 rtc::Thread::Current(),
72 rtc::Thread::Current(),
73 fake_transport_controller_.get()) {
74 fake_transport_controller_->use_quic();
75 quic_data_transport_.set_content_name("data");
76 quic_data_transport_.SetTransport(kTransportName);
77 ice_transport_channel_ = static_cast<FakeTransportChannel*>(
78 quic_data_transport_.quic_transport_channel()->ice_transport_channel());
79 ice_transport_channel_->SetAsync(true);
80 }
81
82 void GenerateCertificateAndFingerprint() {
83 rtc::scoped_refptr<rtc::RTCCertificate> local_cert =
84 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
85 rtc::SSLIdentity::Generate("cert_name", rtc::KT_DEFAULT)));
86 quic_data_transport_.quic_transport_channel()->SetLocalCertificate(
87 local_cert);
88 local_fingerprint_.reset(CreateFingerprint(local_cert.get()));
89 }
90
91 // Connects |ice_transport_channel_| to that of the other peer.
92 void Connect(QuicDataTransportPeer* other_peer) {
93 ice_transport_channel_->SetDestination(other_peer->ice_transport_channel_);
94 }
95
96 std::unique_ptr<rtc::SSLFingerprint>& local_fingerprint() {
97 return local_fingerprint_;
98 }
99
100 QuicTransportChannel* quic_transport_channel() {
101 return quic_data_transport_.quic_transport_channel();
102 }
103
104 // Write a messge directly to the ReliableQuicStream.
105 void WriteMessage(int data_channel_id,
106 uint64_t message_id,
107 const std::string& message) {
108 ReliableQuicStream* stream =
109 quic_data_transport_.quic_transport_channel()->CreateQuicStream();
110 rtc::CopyOnWriteBuffer payload;
111 webrtc::WriteQuicDataChannelMessageHeader(data_channel_id, message_id,
112 &payload);
113 stream->Write(payload.data<char>(), payload.size(), false);
114 stream->Write(message.data(), message.size(), true);
115 }
116
117 rtc::scoped_refptr<DataChannelInterface> CreateDataChannel(
118 const DataChannelInit* config) {
119 return quic_data_transport_.CreateDataChannel("testing", config);
120 }
121
122 QuicDataTransport* quic_data_transport() { return &quic_data_transport_; }
123
124 private:
125 // Creates a fingerprint from a certificate.
126 rtc::SSLFingerprint* CreateFingerprint(rtc::RTCCertificate* cert) {
127 std::string digest_algorithm;
128 cert->ssl_certificate().GetSignatureDigestAlgorithm(&digest_algorithm);
129 std::unique_ptr<rtc::SSLFingerprint> fingerprint(
130 rtc::SSLFingerprint::Create(digest_algorithm, cert->identity()));
131 return fingerprint.release();
132 }
133
134 std::unique_ptr<FakeTransportController> fake_transport_controller_;
135 QuicDataTransport quic_data_transport_;
136 FakeTransportChannel* ice_transport_channel_;
137 std::unique_ptr<rtc::SSLFingerprint> local_fingerprint_;
138 };
139
140 class QuicDataTransportTest : public testing::Test {
141 public:
142 QuicDataTransportTest() {}
143
144 void ConnectTransportChannels() {
145 SetCryptoParameters();
146 peer1_.Connect(&peer2_);
147 ASSERT_TRUE_WAIT(peer1_.quic_transport_channel()->writable() &&
148 peer2_.quic_transport_channel()->writable(),
149 kTimeoutMs);
150 }
151
152 // Sets crypto parameters required for the QUIC handshake.
153 void SetCryptoParameters() {
154 peer1_.GenerateCertificateAndFingerprint();
155 peer2_.GenerateCertificateAndFingerprint();
156
157 peer1_.quic_transport_channel()->SetSslRole(rtc::SSL_CLIENT);
158 peer2_.quic_transport_channel()->SetSslRole(rtc::SSL_SERVER);
159
160 std::unique_ptr<rtc::SSLFingerprint>& peer1_fingerprint =
161 peer1_.local_fingerprint();
162 std::unique_ptr<rtc::SSLFingerprint>& peer2_fingerprint =
163 peer2_.local_fingerprint();
164
165 peer1_.quic_transport_channel()->SetRemoteFingerprint(
166 peer2_fingerprint->algorithm,
167 reinterpret_cast<const uint8_t*>(peer2_fingerprint->digest.data()),
168 peer2_fingerprint->digest.size());
169 peer2_.quic_transport_channel()->SetRemoteFingerprint(
170 peer1_fingerprint->algorithm,
171 reinterpret_cast<const uint8_t*>(peer1_fingerprint->digest.data()),
172 peer1_fingerprint->digest.size());
173 }
174
175 protected:
176 QuicDataTransportPeer peer1_;
177 QuicDataTransportPeer peer2_;
178 };
179
180 // Tests creation and destruction of data channels.
181 TEST_F(QuicDataTransportTest, CreateAndDestroyDataChannels) {
182 QuicDataTransport* quic_data_transport = peer2_.quic_data_transport();
183 EXPECT_FALSE(quic_data_transport->HasDataChannels());
184 for (int data_channel_id = 0; data_channel_id < 5; ++data_channel_id) {
185 EXPECT_FALSE(quic_data_transport->HasDataChannel(data_channel_id));
186 webrtc::DataChannelInit config;
187 config.id = data_channel_id;
188 rtc::scoped_refptr<DataChannelInterface> data_channel =
189 peer2_.CreateDataChannel(&config);
190 EXPECT_NE(nullptr, data_channel);
191 EXPECT_EQ(data_channel_id, data_channel->id());
192 EXPECT_TRUE(quic_data_transport->HasDataChannel(data_channel_id));
193 }
194 EXPECT_TRUE(quic_data_transport->HasDataChannels());
195 for (int data_channel_id = 0; data_channel_id < 5; ++data_channel_id) {
196 quic_data_transport->DestroyDataChannel(data_channel_id);
197 EXPECT_FALSE(quic_data_transport->HasDataChannel(data_channel_id));
198 }
199 EXPECT_FALSE(quic_data_transport->HasDataChannels());
200 }
201
202 // Tests that the QuicDataTransport does not allow creating multiple
203 // QuicDataChannels with the same id.
204 TEST_F(QuicDataTransportTest, CannotCreateDataChannelsWithSameId) {
205 webrtc::DataChannelInit config;
206 config.id = 2;
207 EXPECT_NE(nullptr, peer2_.CreateDataChannel(&config));
208 EXPECT_EQ(nullptr, peer2_.CreateDataChannel(&config));
209 }
210
211 // Tests that any data channels created by the QuicDataTransport are in state
212 // kConnecting before the QuicTransportChannel is set, then transition to state
213 // kOpen when the transport channel becomes writable.
214 TEST_F(QuicDataTransportTest, DataChannelsOpenWhenTransportChannelWritable) {
215 webrtc::DataChannelInit config1;
216 config1.id = 7;
217 rtc::scoped_refptr<DataChannelInterface> data_channel1 =
218 peer2_.CreateDataChannel(&config1);
219 EXPECT_EQ(webrtc::DataChannelInterface::kConnecting, data_channel1->state());
220 EXPECT_EQ(webrtc::DataChannelInterface::kConnecting, data_channel1->state());
221 webrtc::DataChannelInit config2;
222 config2.id = 14;
223 rtc::scoped_refptr<DataChannelInterface> data_channel2 =
224 peer2_.CreateDataChannel(&config2);
225 EXPECT_EQ(webrtc::DataChannelInterface::kConnecting, data_channel2->state());
226 // Existing data channels should open once the transport channel is writable.
227 ConnectTransportChannels();
228 EXPECT_EQ_WAIT(webrtc::DataChannelInterface::kOpen, data_channel1->state(),
229 kTimeoutMs);
230 EXPECT_EQ_WAIT(webrtc::DataChannelInterface::kOpen, data_channel2->state(),
231 kTimeoutMs);
232 // Any data channels created afterwards should start in state kOpen.
233 webrtc::DataChannelInit config3;
234 config3.id = 21;
235 rtc::scoped_refptr<DataChannelInterface> data_channel3 =
236 peer2_.CreateDataChannel(&config3);
237 EXPECT_EQ(webrtc::DataChannelInterface::kOpen, data_channel3->state());
238 }
239
240 // Tests that the QuicTransport dispatches messages for one QuicDataChannel.
241 TEST_F(QuicDataTransportTest, ReceiveMessagesForSingleDataChannel) {
242 ConnectTransportChannels();
243
244 int data_channel_id = 1337;
245 webrtc::DataChannelInit config;
246 config.id = data_channel_id;
247 rtc::scoped_refptr<DataChannelInterface> peer2_data_channel =
248 peer2_.CreateDataChannel(&config);
249 FakeObserver observer;
250 peer2_data_channel->RegisterObserver(&observer);
251
252 uint64_t message1_id = 26u;
253 peer1_.WriteMessage(data_channel_id, message1_id, "Testing");
254 ASSERT_EQ_WAIT(1, observer.messages_received(), kTimeoutMs);
255 EXPECT_EQ("Testing", observer.messages()[0]);
256
257 uint64_t message2_id = 402u;
258 peer1_.WriteMessage(data_channel_id, message2_id, "Hello, World!");
259 ASSERT_EQ_WAIT(2, observer.messages_received(), kTimeoutMs);
260 EXPECT_EQ("Hello, World!", observer.messages()[1]);
261
262 uint64_t message3_id = 100260415u;
263 peer1_.WriteMessage(data_channel_id, message3_id, "Third message");
264 ASSERT_EQ_WAIT(3, observer.messages_received(), kTimeoutMs);
265 EXPECT_EQ("Third message", observer.messages()[2]);
266 }
267
268 // Tests that the QuicTransport dispatches messages to the correct data channel
269 // when multiple are in use.
270 TEST_F(QuicDataTransportTest, ReceiveMessagesForMultipleDataChannels) {
271 ConnectTransportChannels();
272
273 std::vector<rtc::scoped_refptr<DataChannelInterface>> data_channels;
274 for (int data_channel_id = 0; data_channel_id < 5; ++data_channel_id) {
275 webrtc::DataChannelInit config;
276 config.id = data_channel_id;
277 data_channels.push_back(peer2_.CreateDataChannel(&config));
278 }
279
280 for (int data_channel_id = 0; data_channel_id < 5; ++data_channel_id) {
281 uint64_t message1_id = 48023u;
282 FakeObserver observer;
283 DataChannelInterface* peer2_data_channel =
284 data_channels[data_channel_id].get();
285 peer2_data_channel->RegisterObserver(&observer);
286 peer1_.WriteMessage(data_channel_id, message1_id, "Testing");
287 ASSERT_EQ_WAIT(1, observer.messages_received(), kTimeoutMs);
288 EXPECT_EQ("Testing", observer.messages()[0]);
289
290 uint64_t message2_id = 1372643095u;
291 peer1_.WriteMessage(data_channel_id, message2_id, "Hello, World!");
292 ASSERT_EQ_WAIT(2, observer.messages_received(), kTimeoutMs);
293 EXPECT_EQ("Hello, World!", observer.messages()[1]);
294 }
295 }
296
297 // Tests end-to-end that both peers can use multiple QuicDataChannels to
298 // send/receive messages using a QuicDataTransport.
299 TEST_F(QuicDataTransportTest, EndToEndSendReceiveMessages) {
300 ConnectTransportChannels();
301
302 std::vector<rtc::scoped_refptr<DataChannelInterface>> peer1_data_channels;
303 std::vector<rtc::scoped_refptr<DataChannelInterface>> peer2_data_channels;
304
305 for (int data_channel_id = 0; data_channel_id < 5; ++data_channel_id) {
306 webrtc::DataChannelInit config;
307 config.id = data_channel_id;
308 peer1_data_channels.push_back(peer1_.CreateDataChannel(&config));
309 peer2_data_channels.push_back(peer2_.CreateDataChannel(&config));
310 }
311
312 for (int data_channel_id = 0; data_channel_id < 5; ++data_channel_id) {
313 DataChannelInterface* peer1_data_channel =
314 peer1_data_channels[data_channel_id].get();
315 FakeObserver observer1;
316 peer1_data_channel->RegisterObserver(&observer1);
317 DataChannelInterface* peer2_data_channel =
318 peer2_data_channels[data_channel_id].get();
319 FakeObserver observer2;
320 peer2_data_channel->RegisterObserver(&observer2);
321
322 peer1_data_channel->Send(webrtc::DataBuffer("Peer 1 message 1"));
323 ASSERT_EQ_WAIT(1, observer2.messages_received(), kTimeoutMs);
324 EXPECT_EQ("Peer 1 message 1", observer2.messages()[0]);
325
326 peer1_data_channel->Send(webrtc::DataBuffer("Peer 1 message 2"));
327 ASSERT_EQ_WAIT(2, observer2.messages_received(), kTimeoutMs);
328 EXPECT_EQ("Peer 1 message 2", observer2.messages()[1]);
329
330 peer2_data_channel->Send(webrtc::DataBuffer("Peer 2 message 1"));
331 ASSERT_EQ_WAIT(1, observer1.messages_received(), kTimeoutMs);
332 EXPECT_EQ("Peer 2 message 1", observer1.messages()[0]);
333
334 peer2_data_channel->Send(webrtc::DataBuffer("Peer 2 message 2"));
335 ASSERT_EQ_WAIT(2, observer1.messages_received(), kTimeoutMs);
336 EXPECT_EQ("Peer 2 message 2", observer1.messages()[1]);
337 }
338 }
339
340 // Tests that SetTransport returns false when setting a transport that is not
341 // equivalent to the one already set.
342 TEST_F(QuicDataTransportTest, SetTransportReturnValue) {
343 QuicDataTransport* quic_data_transport = peer1_.quic_data_transport();
344 // Ignore the same transport name.
345 EXPECT_TRUE(quic_data_transport->SetTransport(kTransportName));
346 // Return false when setting a different transport name.
347 EXPECT_FALSE(quic_data_transport->SetTransport("another transport name"));
348 }
349
350 } // namespace
OLDNEW
« no previous file with comments | « webrtc/api/quicdatatransport.cc ('k') | webrtc/api/remoteaudiosource.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698