blob: e2bdf449b998fc5a73d3d8a77ef5ad4b54975203 [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 {}
35 bool Start(int local_port, int remote_port) override { return true; }
36 bool OpenStream(int sid) override { return true; }
37 bool ResetStream(int sid) override { return true; }
38 bool SendData(const cricket::SendDataParams& params,
39 const rtc::CopyOnWriteBuffer& payload,
40 cricket::SendDataResult* result = nullptr) override {
41 return true;
42 }
43 bool ReadyToSendData() override { return true; }
44 void set_debug_name_for_testing(const char* debug_name) override {}
45 // Methods exposed for testing
46 void SendSignalReadyToSendData() { SignalReadyToSendData(); }
47
48 void SendSignalClosingProcedureStartedRemotely() {
49 SignalClosingProcedureStartedRemotely(1);
50 }
51
52 void SendSignalClosingProcedureComplete() {
53 SignalClosingProcedureComplete(1);
54 }
55};
56
57} // namespace
58
59class TestSctpTransportObserver : public SctpTransportObserverInterface {
60 public:
61 void OnStateChange(SctpTransportInformation info) override {
62 states_.push_back(info.state());
63 }
64
65 SctpTransportState State() {
66 if (states_.size() > 0) {
67 return states_[states_.size() - 1];
68 } else {
69 return SctpTransportState::kNew;
70 }
71 }
72
73 const std::vector<SctpTransportState>& States() { return states_; }
74
75 private:
76 std::vector<SctpTransportState> states_;
77};
78
79class SctpTransportTest : public testing::Test {
80 public:
81 SctpTransport* transport() { return transport_.get(); }
82 SctpTransportObserverInterface* observer() { return &observer_; }
83
84 void CreateTransport() {
85 auto cricket_sctp_transport =
86 absl::WrapUnique(new FakeCricketSctpTransport());
87 transport_ = new rtc::RefCountedObject<SctpTransport>(
88 std::move(cricket_sctp_transport));
89 }
90
91 void AddDtlsTransport() {
92 std::unique_ptr<cricket::DtlsTransportInternal> cricket_transport =
93 absl::make_unique<FakeDtlsTransport>(
94 "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
95 dtls_transport_ =
96 new rtc::RefCountedObject<DtlsTransport>(std::move(cricket_transport));
97 transport_->SetDtlsTransport(dtls_transport_);
98 }
99
100 void CompleteSctpHandshake() {
101 CricketSctpTransport()->SendSignalReadyToSendData();
102 }
103
104 FakeCricketSctpTransport* CricketSctpTransport() {
105 return static_cast<FakeCricketSctpTransport*>(transport_->internal());
106 }
107
108 rtc::scoped_refptr<SctpTransport> transport_;
109 rtc::scoped_refptr<DtlsTransport> dtls_transport_;
110 TestSctpTransportObserver observer_;
111};
112
113TEST(SctpTransportSimpleTest, CreateClearDelete) {
114 std::unique_ptr<cricket::SctpTransportInternal> fake_cricket_sctp_transport =
115 absl::WrapUnique(new FakeCricketSctpTransport());
116 rtc::scoped_refptr<SctpTransport> sctp_transport =
117 new rtc::RefCountedObject<SctpTransport>(
118 std::move(fake_cricket_sctp_transport));
119 ASSERT_TRUE(sctp_transport->internal());
120 ASSERT_EQ(SctpTransportState::kNew, sctp_transport->Information().state());
121 sctp_transport->Clear();
122 ASSERT_FALSE(sctp_transport->internal());
123 ASSERT_EQ(SctpTransportState::kClosed, sctp_transport->Information().state());
124}
125
126TEST_F(SctpTransportTest, EventsObservedWhenConnecting) {
127 CreateTransport();
128 transport()->RegisterObserver(observer());
129 AddDtlsTransport();
130 CompleteSctpHandshake();
131 ASSERT_EQ_WAIT(SctpTransportState::kConnected, observer_.State(),
132 kDefaultTimeout);
133 EXPECT_THAT(observer_.States(), ElementsAre(SctpTransportState::kConnecting,
134 SctpTransportState::kConnected));
135}
136
137TEST_F(SctpTransportTest, CloseWhenClearing) {
138 CreateTransport();
139 transport()->RegisterObserver(observer());
140 AddDtlsTransport();
141 CompleteSctpHandshake();
142 ASSERT_EQ_WAIT(SctpTransportState::kConnected, observer_.State(),
143 kDefaultTimeout);
144 transport()->Clear();
145 ASSERT_EQ_WAIT(SctpTransportState::kClosed, observer_.State(),
146 kDefaultTimeout);
147}
148
149} // namespace webrtc