webrtc_transport_unittest.cc 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467
  1. // Copyright 2015 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "remoting/protocol/webrtc_transport.h"
  5. #include <utility>
  6. #include "base/bind.h"
  7. #include "base/callback_helpers.h"
  8. #include "base/memory/raw_ptr.h"
  9. #include "base/run_loop.h"
  10. #include "base/strings/string_util.h"
  11. #include "base/test/bind.h"
  12. #include "base/test/task_environment.h"
  13. #include "base/threading/platform_thread.h"
  14. #include "base/threading/watchdog.h"
  15. #include "base/time/time.h"
  16. #include "build/build_config.h"
  17. #include "components/webrtc/thread_wrapper.h"
  18. #include "net/base/io_buffer.h"
  19. #include "net/url_request/url_request_context_getter.h"
  20. #include "remoting/base/compound_buffer.h"
  21. #include "remoting/proto/event.pb.h"
  22. #include "remoting/protocol/fake_authenticator.h"
  23. #include "remoting/protocol/message_channel_factory.h"
  24. #include "remoting/protocol/message_pipe.h"
  25. #include "remoting/protocol/message_serialization.h"
  26. #include "remoting/protocol/network_settings.h"
  27. #include "remoting/protocol/transport_context.h"
  28. #include "remoting/protocol/webrtc_video_encoder_factory.h"
  29. #include "remoting/signaling/fake_signal_strategy.h"
  30. #include "testing/gtest/include/gtest/gtest.h"
  31. #include "third_party/libjingle_xmpp/xmllite/xmlelement.h"
  32. namespace remoting {
  33. namespace protocol {
  34. namespace {
  35. const char kChannelName[] = "test_channel";
  36. const char kAuthKey[] = "test_auth_key";
  37. class TestTransportEventHandler : public WebrtcTransport::EventHandler {
  38. public:
  39. typedef base::RepeatingCallback<void(ErrorCode error)> ErrorCallback;
  40. typedef base::RepeatingCallback<void(const std::string& name,
  41. std::unique_ptr<MessagePipe> pipe)>
  42. IncomingChannelCallback;
  43. TestTransportEventHandler() = default;
  44. TestTransportEventHandler(const TestTransportEventHandler&) = delete;
  45. TestTransportEventHandler& operator=(const TestTransportEventHandler&) =
  46. delete;
  47. ~TestTransportEventHandler() override = default;
  48. // All callbacks must be set before the test handler is passed to a Transport
  49. // object.
  50. void set_connecting_callback(const base::RepeatingClosure& callback) {
  51. connecting_callback_ = callback;
  52. }
  53. void set_connected_callback(const base::RepeatingClosure& callback) {
  54. connected_callback_ = callback;
  55. }
  56. void set_error_callback(const ErrorCallback& callback) {
  57. error_callback_ = callback;
  58. }
  59. void set_incoming_channel_callback(const IncomingChannelCallback& callback) {
  60. incoming_channel_callback_ = callback;
  61. }
  62. // WebrtcTransport::EventHandler interface.
  63. void OnWebrtcTransportConnecting() override {
  64. if (!connecting_callback_.is_null())
  65. connecting_callback_.Run();
  66. }
  67. void OnWebrtcTransportConnected() override {
  68. if (!connected_callback_.is_null())
  69. connected_callback_.Run();
  70. }
  71. void OnWebrtcTransportError(ErrorCode error) override {
  72. error_callback_.Run(error);
  73. }
  74. void OnWebrtcTransportProtocolChanged() override {}
  75. void OnWebrtcTransportIncomingDataChannel(
  76. const std::string& name,
  77. std::unique_ptr<MessagePipe> pipe) override {
  78. if (incoming_channel_callback_) {
  79. incoming_channel_callback_.Run(name, std::move(pipe));
  80. } else {
  81. FAIL() << "Received unexpected incoming channel.";
  82. }
  83. }
  84. void OnWebrtcTransportMediaStreamAdded(
  85. rtc::scoped_refptr<webrtc::MediaStreamInterface> stream) override {}
  86. void OnWebrtcTransportMediaStreamRemoved(
  87. rtc::scoped_refptr<webrtc::MediaStreamInterface> stream) override {}
  88. void OnWebrtcTransportRouteChanged(const TransportRoute& route) override {}
  89. private:
  90. base::RepeatingClosure connecting_callback_;
  91. base::RepeatingClosure connected_callback_;
  92. ErrorCallback error_callback_;
  93. IncomingChannelCallback incoming_channel_callback_;
  94. };
  95. class TestMessagePipeEventHandler : public MessagePipe::EventHandler {
  96. public:
  97. TestMessagePipeEventHandler() = default;
  98. TestMessagePipeEventHandler(const TestMessagePipeEventHandler&) = delete;
  99. TestMessagePipeEventHandler& operator=(const TestMessagePipeEventHandler&) =
  100. delete;
  101. ~TestMessagePipeEventHandler() override = default;
  102. void set_open_callback(const base::RepeatingClosure& callback) {
  103. open_callback_ = callback;
  104. }
  105. void set_message_callback(const base::RepeatingClosure& callback) {
  106. message_callback_ = callback;
  107. }
  108. void set_closed_callback(const base::RepeatingClosure& callback) {
  109. closed_callback_ = callback;
  110. }
  111. bool is_open() { return is_open_; }
  112. const std::list<std::unique_ptr<CompoundBuffer>>& received_messages() {
  113. return received_messages_;
  114. }
  115. // MessagePipe::EventHandler interface.
  116. void OnMessagePipeOpen() override {
  117. is_open_ = true;
  118. if (!open_callback_.is_null())
  119. open_callback_.Run();
  120. }
  121. void OnMessageReceived(std::unique_ptr<CompoundBuffer> message) override {
  122. received_messages_.push_back(std::move(message));
  123. if (!message_callback_.is_null())
  124. message_callback_.Run();
  125. }
  126. void OnMessagePipeClosed() override {
  127. if (!closed_callback_.is_null()) {
  128. closed_callback_.Run();
  129. } else {
  130. FAIL() << "Channel closed unexpectedly.";
  131. }
  132. }
  133. private:
  134. bool is_open_ = false;
  135. base::RepeatingClosure open_callback_;
  136. base::RepeatingClosure message_callback_;
  137. base::RepeatingClosure closed_callback_;
  138. std::list<std::unique_ptr<CompoundBuffer>> received_messages_;
  139. };
  140. } // namespace
  141. class WebrtcTransportTest : public testing::Test {
  142. public:
  143. WebrtcTransportTest()
  144. : task_environment_(base::test::TaskEnvironment::MainThreadType::IO) {
  145. webrtc::ThreadWrapper::EnsureForCurrentMessageLoop();
  146. network_settings_ =
  147. NetworkSettings(NetworkSettings::NAT_TRAVERSAL_OUTGOING);
  148. }
  149. void TearDown() override {
  150. run_loop_.reset();
  151. client_message_pipe_.reset();
  152. client_transport_.reset();
  153. host_message_pipe_.reset();
  154. host_transport_.reset();
  155. base::RunLoop().RunUntilIdle();
  156. }
  157. void ProcessTransportInfo(std::unique_ptr<WebrtcTransport>* target_transport,
  158. bool normalize_line_endings,
  159. std::unique_ptr<jingle_xmpp::XmlElement> transport_info) {
  160. ASSERT_TRUE(target_transport);
  161. // Reformat the message to normalize line endings by removing CR symbol.
  162. if (normalize_line_endings) {
  163. std::string xml = transport_info->Str();
  164. base::ReplaceChars(xml, "\r", std::string(), &xml);
  165. transport_info.reset(jingle_xmpp::XmlElement::ForStr(xml));
  166. }
  167. EXPECT_TRUE(
  168. (*target_transport)->ProcessTransportInfo(transport_info.get()));
  169. }
  170. void InitializeConnection() {
  171. host_transport_ = std::make_unique<WebrtcTransport>(
  172. webrtc::ThreadWrapper::current(),
  173. TransportContext::ForTests(TransportRole::SERVER),
  174. std::make_unique<WebrtcVideoEncoderFactory>(), &host_event_handler_);
  175. // If offer_to_receive_video and offer_to_receive_audio are both false,
  176. // there must be a stream present in order to generate a valid SDP offer.
  177. host_transport_->peer_connection()->AddTransceiver(
  178. cricket::MEDIA_TYPE_VIDEO);
  179. host_authenticator_ =
  180. std::make_unique<FakeAuthenticator>(FakeAuthenticator::ACCEPT);
  181. host_authenticator_->set_auth_key(kAuthKey);
  182. client_transport_ = std::make_unique<WebrtcTransport>(
  183. webrtc::ThreadWrapper::current(),
  184. TransportContext::ForTests(TransportRole::CLIENT), nullptr,
  185. &client_event_handler_);
  186. client_authenticator_ =
  187. std::make_unique<FakeAuthenticator>(FakeAuthenticator::ACCEPT);
  188. client_authenticator_->set_auth_key(kAuthKey);
  189. }
  190. void StartConnection() {
  191. host_event_handler_.set_connected_callback(base::DoNothing());
  192. client_event_handler_.set_connected_callback(base::DoNothing());
  193. host_event_handler_.set_error_callback(
  194. base::BindRepeating(&WebrtcTransportTest::OnSessionError,
  195. base::Unretained(this), TransportRole::SERVER));
  196. client_event_handler_.set_error_callback(
  197. base::BindRepeating(&WebrtcTransportTest::OnSessionError,
  198. base::Unretained(this), TransportRole::CLIENT));
  199. // Start both transports.
  200. host_transport_->Start(
  201. host_authenticator_.get(),
  202. base::BindRepeating(&WebrtcTransportTest::ProcessTransportInfo,
  203. base::Unretained(this), &client_transport_, true));
  204. client_transport_->Start(
  205. client_authenticator_.get(),
  206. base::BindRepeating(&WebrtcTransportTest::ProcessTransportInfo,
  207. base::Unretained(this), &host_transport_, false));
  208. }
  209. void WaitUntilConnected() {
  210. int counter = 2;
  211. host_event_handler_.set_connected_callback(
  212. base::BindRepeating(&WebrtcTransportTest::QuitRunLoopOnCounter,
  213. base::Unretained(this), &counter));
  214. client_event_handler_.set_connected_callback(
  215. base::BindRepeating(&WebrtcTransportTest::QuitRunLoopOnCounter,
  216. base::Unretained(this), &counter));
  217. run_loop_ = std::make_unique<base::RunLoop>();
  218. run_loop_->Run();
  219. host_event_handler_.set_connected_callback({});
  220. client_event_handler_.set_connected_callback({});
  221. EXPECT_EQ(OK, client_error_);
  222. EXPECT_EQ(OK, host_error_);
  223. }
  224. void ExpectClientDataStream() {
  225. client_event_handler_.set_incoming_channel_callback(base::BindRepeating(
  226. &WebrtcTransportTest::OnIncomingChannel, base::Unretained(this)));
  227. }
  228. void CreateHostDataStream() {
  229. host_message_pipe_ = host_transport_->CreateOutgoingChannel(kChannelName);
  230. host_message_pipe_->Start(&host_message_pipe_event_handler_);
  231. host_message_pipe_event_handler_.set_open_callback(base::BindRepeating(
  232. &WebrtcTransportTest::OnHostChannelConnected, base::Unretained(this)));
  233. }
  234. void OnIncomingChannel(const std::string& name,
  235. std::unique_ptr<MessagePipe> pipe) {
  236. EXPECT_EQ(kChannelName, name);
  237. client_message_pipe_ = std::move(pipe);
  238. client_message_pipe_->Start(&client_message_pipe_event_handler_);
  239. if (run_loop_ && host_message_pipe_event_handler_.is_open())
  240. run_loop_->Quit();
  241. }
  242. void OnHostChannelConnected() {
  243. if (run_loop_ && client_message_pipe_event_handler_.is_open())
  244. run_loop_->Quit();
  245. }
  246. void OnSessionError(TransportRole role, ErrorCode error) {
  247. if (role == TransportRole::SERVER) {
  248. host_error_ = error;
  249. if (destroy_on_error_) {
  250. host_message_pipe_.reset();
  251. host_transport_.reset();
  252. }
  253. } else {
  254. CHECK(role == TransportRole::CLIENT);
  255. client_error_ = error;
  256. if (destroy_on_error_) {
  257. client_message_pipe_.reset();
  258. client_transport_.reset();
  259. }
  260. }
  261. run_loop_->Quit();
  262. }
  263. void OnHostChannelClosed() {
  264. host_message_pipe_.reset();
  265. run_loop_->Quit();
  266. }
  267. void QuitRunLoopOnCounter(int* counter) {
  268. --(*counter);
  269. if (*counter == 0)
  270. run_loop_->Quit();
  271. }
  272. protected:
  273. base::test::TaskEnvironment task_environment_;
  274. std::unique_ptr<base::RunLoop> run_loop_;
  275. NetworkSettings network_settings_;
  276. std::unique_ptr<WebrtcTransport> host_transport_;
  277. TestTransportEventHandler host_event_handler_;
  278. std::unique_ptr<FakeAuthenticator> host_authenticator_;
  279. std::unique_ptr<WebrtcTransport> client_transport_;
  280. TestTransportEventHandler client_event_handler_;
  281. std::unique_ptr<FakeAuthenticator> client_authenticator_;
  282. std::unique_ptr<MessagePipe> client_message_pipe_;
  283. TestMessagePipeEventHandler client_message_pipe_event_handler_;
  284. std::unique_ptr<MessagePipe> host_message_pipe_;
  285. TestMessagePipeEventHandler host_message_pipe_event_handler_;
  286. ErrorCode client_error_ = OK;
  287. ErrorCode host_error_ = OK;
  288. bool destroy_on_error_ = false;
  289. };
  290. // crbug.com/1224862: Tests are flaky on Mac.
  291. #if BUILDFLAG(IS_MAC)
  292. #define MAYBE_Connects DISABLED_Connects
  293. #else
  294. #define MAYBE_Connects Connects
  295. #endif
  296. TEST_F(WebrtcTransportTest, MAYBE_Connects) {
  297. InitializeConnection();
  298. StartConnection();
  299. WaitUntilConnected();
  300. }
  301. TEST_F(WebrtcTransportTest, InvalidAuthKey) {
  302. InitializeConnection();
  303. client_authenticator_->set_auth_key("Incorrect Key");
  304. StartConnection();
  305. run_loop_ = std::make_unique<base::RunLoop>();
  306. run_loop_->Run();
  307. EXPECT_EQ(AUTHENTICATION_FAILED, client_error_);
  308. }
  309. // crbug.com/1224862: Tests are flaky on Mac.
  310. #if BUILDFLAG(IS_MAC)
  311. #define MAYBE_DataStream DISABLED_DataStream
  312. #else
  313. #define MAYBE_DataStream DataStream
  314. #endif
  315. TEST_F(WebrtcTransportTest, MAYBE_DataStream) {
  316. client_event_handler_.set_connecting_callback(base::BindRepeating(
  317. &WebrtcTransportTest::ExpectClientDataStream, base::Unretained(this)));
  318. host_event_handler_.set_connecting_callback(base::BindRepeating(
  319. &WebrtcTransportTest::CreateHostDataStream, base::Unretained(this)));
  320. InitializeConnection();
  321. StartConnection();
  322. run_loop_ = std::make_unique<base::RunLoop>();
  323. run_loop_->Run();
  324. EXPECT_TRUE(client_message_pipe_);
  325. EXPECT_TRUE(host_message_pipe_);
  326. TextEvent message;
  327. message.set_text("Hello");
  328. host_message_pipe_->Send(&message, {});
  329. run_loop_ = std::make_unique<base::RunLoop>();
  330. client_message_pipe_event_handler_.set_message_callback(
  331. run_loop_->QuitClosure());
  332. run_loop_->Run();
  333. ASSERT_EQ(1U, client_message_pipe_event_handler_.received_messages().size());
  334. std::unique_ptr<TextEvent> received_message = ParseMessage<TextEvent>(
  335. client_message_pipe_event_handler_.received_messages().front().get());
  336. EXPECT_EQ(message.text(), received_message->text());
  337. }
  338. // crbug.com/1224862: Tests are flaky on Mac.
  339. #if BUILDFLAG(IS_MAC)
  340. #define MAYBE_DataStreamLate DISABLED_DataStreamLate
  341. #else
  342. #define MAYBE_DataStreamLate DataStreamLate
  343. #endif
  344. // Verify that data streams can be created after connection has been initiated.
  345. TEST_F(WebrtcTransportTest, MAYBE_DataStreamLate) {
  346. InitializeConnection();
  347. StartConnection();
  348. WaitUntilConnected();
  349. ExpectClientDataStream();
  350. CreateHostDataStream();
  351. run_loop_ = std::make_unique<base::RunLoop>();
  352. run_loop_->Run();
  353. EXPECT_TRUE(client_message_pipe_);
  354. EXPECT_TRUE(host_message_pipe_);
  355. }
  356. // crbug.com/1224862: Tests are flaky on Mac.
  357. #if BUILDFLAG(IS_MAC)
  358. #define MAYBE_TerminateDataChannel DISABLED_TerminateDataChannel
  359. #else
  360. #define MAYBE_TerminateDataChannel TerminateDataChannel
  361. #endif
  362. TEST_F(WebrtcTransportTest, MAYBE_TerminateDataChannel) {
  363. InitializeConnection();
  364. StartConnection();
  365. WaitUntilConnected();
  366. ExpectClientDataStream();
  367. CreateHostDataStream();
  368. run_loop_ = std::make_unique<base::RunLoop>();
  369. run_loop_->Run();
  370. EXPECT_TRUE(client_message_pipe_);
  371. EXPECT_TRUE(host_message_pipe_);
  372. destroy_on_error_ = true;
  373. // Expect that the channel is closed on the host side once the client closes
  374. // the channel.
  375. host_message_pipe_event_handler_.set_closed_callback(base::BindRepeating(
  376. &WebrtcTransportTest::OnHostChannelClosed, base::Unretained(this)));
  377. // Destroy pipe on one side of the of the connection. It should get closed on
  378. // the other side.
  379. client_message_pipe_.reset();
  380. run_loop_ = std::make_unique<base::RunLoop>();
  381. run_loop_->Run();
  382. // Check that OnHostChannelClosed() has been called.
  383. EXPECT_EQ(OK, host_error_);
  384. EXPECT_FALSE(host_message_pipe_);
  385. }
  386. } // namespace protocol
  387. } // namespace remoting