eche_signaler_unittest.cc 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. // Copyright 2021 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 "ash/webui/eche_app_ui/eche_signaler.h"
  5. #include <memory>
  6. #include <vector>
  7. #include "ash/components/multidevice/logging/logging.h"
  8. #include "ash/services/secure_channel/public/cpp/client/fake_connection_manager.h"
  9. #include "ash/webui/eche_app_ui/proto/exo_messages.pb.h"
  10. #include "base/task/single_thread_task_runner.h"
  11. #include "base/test/metrics/histogram_tester.h"
  12. #include "base/test/task_environment.h"
  13. #include "mojo/public/cpp/bindings/pending_receiver.h"
  14. #include "mojo/public/cpp/bindings/pending_remote.h"
  15. #include "mojo/public/cpp/bindings/receiver.h"
  16. #include "mojo/public/cpp/bindings/remote.h"
  17. #include "testing/gmock/include/gmock/gmock.h"
  18. #include "testing/gtest/include/gtest/gtest.h"
  19. namespace ash {
  20. namespace eche_app {
  21. namespace {
  22. class TaskRunner {
  23. public:
  24. TaskRunner() = default;
  25. ~TaskRunner() = default;
  26. void WaitForResult() { run_loop_.Run(); }
  27. void Finish() { run_loop_.Quit(); }
  28. private:
  29. base::test::SingleThreadTaskEnvironment task_environment_;
  30. base::RunLoop run_loop_;
  31. };
  32. class FakeExchangerClient : public mojom::SignalingMessageExchanger {
  33. public:
  34. FakeExchangerClient() = default;
  35. ~FakeExchangerClient() override = default;
  36. mojo::PendingReceiver<mojom::SignalingMessageExchanger>
  37. CreatePendingReceiver() {
  38. return remote_.BindNewPipeAndPassReceiver();
  39. }
  40. // mojom::SignalingMessageExchanger:
  41. void SendSignalingMessage(const std::vector<uint8_t>& signal) override {
  42. PA_LOG(INFO) << "FakeExchangerClient SendSignalingMessage";
  43. remote_->SendSignalingMessage(signal);
  44. }
  45. // mojom::SignalingMessageExchanger:
  46. void SetSignalingMessageObserver(
  47. mojo::PendingRemote<mojom::SignalingMessageObserver> observer) override {
  48. remote_->SetSignalingMessageObserver(std::move(observer));
  49. }
  50. // mojom::SignalingMessageExchanger:
  51. void TearDownSignaling() override { remote_->TearDownSignaling(); }
  52. private:
  53. mojo::Remote<mojom::SignalingMessageExchanger> remote_;
  54. };
  55. class FakeObserver : public mojom::SignalingMessageObserver {
  56. public:
  57. FakeObserver(mojo::PendingRemote<mojom::SignalingMessageObserver>* remote,
  58. TaskRunner* task_runner)
  59. : receiver_(this, remote->InitWithNewPipeAndPassReceiver()) {
  60. task_runner_ = task_runner;
  61. }
  62. ~FakeObserver() override = default;
  63. const std::vector<uint8_t>& received_signals() const {
  64. return received_signals_;
  65. }
  66. // mojom::SignalingMessageObserver:
  67. void OnReceivedSignalingMessage(const std::vector<uint8_t>& signal) override {
  68. PA_LOG(INFO) << "FakeObserver OnReceivedSignalingMessage";
  69. for (size_t i = 0; i < signal.size(); i++) {
  70. received_signals_.push_back(signal[i]);
  71. }
  72. task_runner_->Finish();
  73. }
  74. private:
  75. TaskRunner* task_runner_;
  76. std::vector<uint8_t> received_signals_;
  77. mojo::Receiver<mojom::SignalingMessageObserver> receiver_;
  78. };
  79. class FakeEcheConnector : public EcheConnector {
  80. public:
  81. FakeEcheConnector(TaskRunner* task_runner) { task_runner_ = task_runner; }
  82. ~FakeEcheConnector() override = default;
  83. const std::vector<proto::ExoMessage>& sent_messages() const {
  84. return sent_messages_;
  85. }
  86. void SendMessage(const proto::ExoMessage message) override {
  87. sent_messages_.push_back(message);
  88. task_runner_->Finish();
  89. }
  90. void Disconnect() override {}
  91. void SendAppsSetupRequest() override {}
  92. void GetAppsAccessStateRequest() override {}
  93. void AttemptNearbyConnection() override {}
  94. private:
  95. TaskRunner* task_runner_;
  96. std::vector<proto::ExoMessage> sent_messages_;
  97. };
  98. } // namespace
  99. class EcheSignalerTest : public testing::Test {
  100. protected:
  101. EcheSignalerTest() = default;
  102. EcheSignalerTest(const EcheSignalerTest&) = delete;
  103. EcheSignalerTest& operator=(const EcheSignalerTest&) = delete;
  104. ~EcheSignalerTest() override = default;
  105. // testing::Test:
  106. void SetUp() override {
  107. signaler_ = std::make_unique<EcheSignaler>(&fake_connector_,
  108. &fake_connection_manager_);
  109. }
  110. std::vector<uint8_t> getSignal(std::string data) {
  111. std::vector<uint8_t> signal(data.begin(), data.end());
  112. return signal;
  113. }
  114. proto::ExoMessage getExoMessage(std::string data) {
  115. std::vector<uint8_t> signal(data.begin(), data.end());
  116. std::string encoded_signal(signal.begin(), signal.end());
  117. proto::SignalingRequest request;
  118. request.set_data(encoded_signal);
  119. proto::ExoMessage message;
  120. *message.mutable_request() = std::move(request);
  121. return message;
  122. }
  123. proto::ExoMessage getTearDownSignalingMessage() const {
  124. proto::SignalingAction action;
  125. action.set_action_type(proto::ActionType::ACTION_TEAR_DOWN);
  126. proto::ExoMessage message;
  127. *message.mutable_action() = std::move(action);
  128. return message;
  129. }
  130. proto::ExoMessage getResponseMessage(std::string data) {
  131. std::vector<uint8_t> signal(data.begin(), data.end());
  132. std::string encoded_signal(signal.begin(), signal.end());
  133. proto::SignalingResponse response;
  134. response.set_data(encoded_signal);
  135. proto::ExoMessage message;
  136. *message.mutable_response() = std::move(response);
  137. return message;
  138. }
  139. void SetConnectionStatus(secure_channel::ConnectionManager::Status status) {
  140. fake_connection_manager_.SetStatus(status);
  141. }
  142. TaskRunner task_runner_;
  143. FakeEcheConnector fake_connector_{&task_runner_};
  144. secure_channel::FakeConnectionManager fake_connection_manager_;
  145. std::unique_ptr<EcheSignaler> signaler_;
  146. };
  147. // Tests SendSignalingMessage.
  148. TEST_F(EcheSignalerTest, TestSendSignalingMessage) {
  149. FakeExchangerClient fake_exchanger_client;
  150. signaler_->Bind(fake_exchanger_client.CreatePendingReceiver());
  151. std::vector<uint8_t> signal = getSignal("123");
  152. fake_exchanger_client.SendSignalingMessage(signal);
  153. task_runner_.WaitForResult();
  154. EXPECT_TRUE(fake_connector_.sent_messages().size() > 0);
  155. }
  156. // Tests TearDownSignaling.
  157. TEST_F(EcheSignalerTest, TestTearDownSignaling) {
  158. FakeExchangerClient fake_exchanger_client;
  159. signaler_->Bind(fake_exchanger_client.CreatePendingReceiver());
  160. proto::ExoMessage tear_down_signaling_message = getTearDownSignalingMessage();
  161. fake_exchanger_client.TearDownSignaling();
  162. task_runner_.WaitForResult();
  163. EXPECT_EQ(fake_connector_.sent_messages()[0].SerializeAsString(),
  164. tear_down_signaling_message.SerializeAsString());
  165. }
  166. // Tests SetSignalingMessageObserver and observer should be triggered when
  167. // message is received.
  168. TEST_F(EcheSignalerTest, TestSetSignalingMessageObserverAndReceiveMessage) {
  169. mojo::PendingRemote<mojom::SignalingMessageObserver> observer;
  170. FakeObserver fake_observer(&observer, &task_runner_);
  171. proto::ExoMessage message = getExoMessage("123");
  172. signaler_->SetSignalingMessageObserver(std::move(observer));
  173. signaler_->OnMessageReceived(message.SerializeAsString());
  174. task_runner_.WaitForResult();
  175. EXPECT_TRUE(fake_observer.received_signals().size() > 0);
  176. }
  177. TEST_F(EcheSignalerTest, TestConnectionFailWhenNoReceiveAnyMessage) {
  178. base::HistogramTester histograms;
  179. mojo::PendingRemote<mojom::SignalingMessageObserver> observer;
  180. FakeObserver fake_observer(&observer, &task_runner_);
  181. SetConnectionStatus(secure_channel::ConnectionManager::Status::kConnected);
  182. histograms.ExpectUniqueSample(
  183. "Eche.StreamEvent.ConnectionFail",
  184. eche_app::mojom::ConnectionFailReason::kSignalingNotTriggered, 0);
  185. signaler_->SetSignalingMessageObserver(std::move(observer));
  186. signaler_->RecordSignalingTimeout();
  187. histograms.ExpectUniqueSample(
  188. "Eche.StreamEvent.ConnectionFail",
  189. eche_app::mojom::ConnectionFailReason::kSignalingNotTriggered, 1);
  190. EXPECT_TRUE(fake_observer.received_signals().size() == 0);
  191. }
  192. TEST_F(EcheSignalerTest, TestConnectionFailWhenSignalingHasLateRequest) {
  193. base::HistogramTester histograms;
  194. mojo::PendingRemote<mojom::SignalingMessageObserver> observer;
  195. FakeObserver fake_observer(&observer, &task_runner_);
  196. proto::ExoMessage message = getExoMessage("123");
  197. SetConnectionStatus(secure_channel::ConnectionManager::Status::kConnected);
  198. histograms.ExpectUniqueSample(
  199. "Eche.StreamEvent.ConnectionFail",
  200. eche_app::mojom::ConnectionFailReason::SignalingHasLateRequest, 0);
  201. signaler_->SetSignalingMessageObserver(std::move(observer));
  202. signaler_->OnMessageReceived(message.SerializeAsString());
  203. task_runner_.WaitForResult();
  204. signaler_->RecordSignalingTimeout();
  205. histograms.ExpectUniqueSample(
  206. "Eche.StreamEvent.ConnectionFail",
  207. eche_app::mojom::ConnectionFailReason::SignalingHasLateRequest, 1);
  208. EXPECT_TRUE(fake_observer.received_signals().size() > 0);
  209. }
  210. TEST_F(EcheSignalerTest, TestConnectionFailWhenSignalingHasLateResponse) {
  211. base::HistogramTester histograms;
  212. mojo::PendingRemote<mojom::SignalingMessageObserver> observer;
  213. FakeObserver fake_observer(&observer, &task_runner_);
  214. proto::ExoMessage message = getResponseMessage("123");
  215. SetConnectionStatus(secure_channel::ConnectionManager::Status::kConnected);
  216. histograms.ExpectUniqueSample(
  217. "Eche.StreamEvent.ConnectionFail",
  218. eche_app::mojom::ConnectionFailReason::SignalingHasLateResponse, 0);
  219. signaler_->SetSignalingMessageObserver(std::move(observer));
  220. signaler_->OnMessageReceived(message.SerializeAsString());
  221. task_runner_.WaitForResult();
  222. signaler_->RecordSignalingTimeout();
  223. histograms.ExpectUniqueSample(
  224. "Eche.StreamEvent.ConnectionFail",
  225. eche_app::mojom::ConnectionFailReason::SignalingHasLateResponse, 1);
  226. EXPECT_TRUE(fake_observer.received_signals().size() > 0);
  227. }
  228. TEST_F(EcheSignalerTest, TestConnectionFailWhenSecurityChannelDisconnected) {
  229. base::HistogramTester histograms;
  230. mojo::PendingRemote<mojom::SignalingMessageObserver> observer;
  231. FakeObserver fake_observer(&observer, &task_runner_);
  232. SetConnectionStatus(secure_channel::ConnectionManager::Status::kDisconnected);
  233. histograms.ExpectUniqueSample(
  234. "Eche.StreamEvent.ConnectionFail",
  235. eche_app::mojom::ConnectionFailReason::kSecurityChannelDisconnected, 0);
  236. signaler_->SetSignalingMessageObserver(std::move(observer));
  237. signaler_->RecordSignalingTimeout();
  238. histograms.ExpectUniqueSample(
  239. "Eche.StreamEvent.ConnectionFail",
  240. eche_app::mojom::ConnectionFailReason::kSecurityChannelDisconnected, 1);
  241. }
  242. } // namespace eche_app
  243. } // namespace ash