blob: 3438b17e3900a7b9e13cc4fe7323abeae41c66a1 [file] [log] [blame]
Harald Alvestrandc85328f2019-02-28 07:51:00 +01001/*
2 * Copyright 2019 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 "pc/sctp_transport.h"
12
13#include <utility>
14#include <vector>
15
16#include "absl/memory/memory.h"
17#include "p2p/base/fake_dtls_transport.h"
18#include "pc/dtls_transport.h"
19#include "rtc_base/gunit.h"
20#include "test/gmock.h"
21#include "test/gtest.h"
22
23constexpr int kDefaultTimeout = 1000; // milliseconds
24
25using cricket::FakeDtlsTransport;
26using ::testing::ElementsAre;
27
28namespace webrtc {
29
30namespace {
31
32class FakeCricketSctpTransport : public cricket::SctpTransportInternal {
33 public:
34 void SetDtlsTransport(rtc::PacketTransportInternal* transport) override {}
Harald Alvestrandfbb45bd2019-05-15 08:07:47 +020035 bool Start(int local_port, int remote_port, int max_message_size) override {
36 return true;
37 }
Harald Alvestrandc85328f2019-02-28 07:51:00 +010038 bool OpenStream(int sid) override { return true; }
39 bool ResetStream(int sid) override { return true; }
40 bool SendData(const cricket::SendDataParams& params,
41 const rtc::CopyOnWriteBuffer& payload,
42 cricket::SendDataResult* result = nullptr) override {
43 return true;
44 }
45 bool ReadyToSendData() override { return true; }
46 void set_debug_name_for_testing(const char* debug_name) override {}
Harald Alvestrandfbb45bd2019-05-15 08:07:47 +020047 int max_message_size() const override { return 0; }
Harald Alvestrandc85328f2019-02-28 07:51:00 +010048 // Methods exposed for testing
49 void SendSignalReadyToSendData() { SignalReadyToSendData(); }
50
51 void SendSignalClosingProcedureStartedRemotely() {
52 SignalClosingProcedureStartedRemotely(1);
53 }
54
55 void SendSignalClosingProcedureComplete() {
56 SignalClosingProcedureComplete(1);
57 }
58};
59
60} // namespace
61
62class TestSctpTransportObserver : public SctpTransportObserverInterface {
63 public:
64 void OnStateChange(SctpTransportInformation info) override {
65 states_.push_back(info.state());
66 }
67
68 SctpTransportState State() {
69 if (states_.size() > 0) {
70 return states_[states_.size() - 1];
71 } else {
72 return SctpTransportState::kNew;
73 }
74 }
75
76 const std::vector<SctpTransportState>& States() { return states_; }
77
78 private:
79 std::vector<SctpTransportState> states_;
80};
81
Mirko Bonadei6a489f22019-04-09 15:11:12 +020082class SctpTransportTest : public ::testing::Test {
Harald Alvestrandc85328f2019-02-28 07:51:00 +010083 public:
84 SctpTransport* transport() { return transport_.get(); }
85 SctpTransportObserverInterface* observer() { return &observer_; }
86
87 void CreateTransport() {
88 auto cricket_sctp_transport =
89 absl::WrapUnique(new FakeCricketSctpTransport());
90 transport_ = new rtc::RefCountedObject<SctpTransport>(
91 std::move(cricket_sctp_transport));
92 }
93
94 void AddDtlsTransport() {
95 std::unique_ptr<cricket::DtlsTransportInternal> cricket_transport =
96 absl::make_unique<FakeDtlsTransport>(
97 "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
98 dtls_transport_ =
99 new rtc::RefCountedObject<DtlsTransport>(std::move(cricket_transport));
100 transport_->SetDtlsTransport(dtls_transport_);
101 }
102
103 void CompleteSctpHandshake() {
104 CricketSctpTransport()->SendSignalReadyToSendData();
105 }
106
107 FakeCricketSctpTransport* CricketSctpTransport() {
108 return static_cast<FakeCricketSctpTransport*>(transport_->internal());
109 }
110
111 rtc::scoped_refptr<SctpTransport> transport_;
112 rtc::scoped_refptr<DtlsTransport> dtls_transport_;
113 TestSctpTransportObserver observer_;
114};
115
116TEST(SctpTransportSimpleTest, CreateClearDelete) {
117 std::unique_ptr<cricket::SctpTransportInternal> fake_cricket_sctp_transport =
118 absl::WrapUnique(new FakeCricketSctpTransport());
119 rtc::scoped_refptr<SctpTransport> sctp_transport =
120 new rtc::RefCountedObject<SctpTransport>(
121 std::move(fake_cricket_sctp_transport));
122 ASSERT_TRUE(sctp_transport->internal());
123 ASSERT_EQ(SctpTransportState::kNew, sctp_transport->Information().state());
124 sctp_transport->Clear();
125 ASSERT_FALSE(sctp_transport->internal());
126 ASSERT_EQ(SctpTransportState::kClosed, sctp_transport->Information().state());
127}
128
129TEST_F(SctpTransportTest, EventsObservedWhenConnecting) {
130 CreateTransport();
131 transport()->RegisterObserver(observer());
132 AddDtlsTransport();
133 CompleteSctpHandshake();
134 ASSERT_EQ_WAIT(SctpTransportState::kConnected, observer_.State(),
135 kDefaultTimeout);
136 EXPECT_THAT(observer_.States(), ElementsAre(SctpTransportState::kConnecting,
137 SctpTransportState::kConnected));
138}
139
140TEST_F(SctpTransportTest, CloseWhenClearing) {
141 CreateTransport();
142 transport()->RegisterObserver(observer());
143 AddDtlsTransport();
144 CompleteSctpHandshake();
145 ASSERT_EQ_WAIT(SctpTransportState::kConnected, observer_.State(),
146 kDefaultTimeout);
147 transport()->Clear();
148 ASSERT_EQ_WAIT(SctpTransportState::kClosed, observer_.State(),
149 kDefaultTimeout);
150}
151
152} // namespace webrtc