mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-15 15:16:12 -04:00
306 lines
10 KiB
C++
306 lines
10 KiB
C++
// Copyright 2020 Google LLC
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// https://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
#include "core/internal/mediums/webrtc.h"
|
|
|
|
#include "core/internal/mediums/webrtc/webrtc_socket_wrapper.h"
|
|
#include "platform/base/listeners.h"
|
|
#include "platform/base/medium_environment.h"
|
|
#include "platform/public/mutex_lock.h"
|
|
#include "gmock/gmock.h"
|
|
#include "gtest/gtest.h"
|
|
|
|
namespace location {
|
|
namespace nearby {
|
|
namespace connections {
|
|
namespace mediums {
|
|
|
|
namespace {
|
|
|
|
class WebRtcTest : public ::testing::Test {
|
|
protected:
|
|
WebRtcTest() {
|
|
MediumEnvironment::Instance().Stop();
|
|
MediumEnvironment::Instance().Start({.webrtc_enabled = true});
|
|
}
|
|
};
|
|
|
|
// Basic test to check that device is accepting connections when initialized.
|
|
TEST_F(WebRtcTest, NotAcceptingConnections) {
|
|
WebRtc webrtc;
|
|
ASSERT_TRUE(webrtc.IsAvailable());
|
|
EXPECT_FALSE(webrtc.IsAcceptingConnections(std::string{}));
|
|
}
|
|
|
|
// Tests the flow when the device tries to accept connections twice. In this
|
|
// case, only the first call is successful and subsequent calls fail.
|
|
TEST_F(WebRtcTest, StartAcceptingConnectionTwice) {
|
|
using MockAcceptedCallback =
|
|
testing::MockFunction<void(WebRtcSocketWrapper socket)>;
|
|
testing::StrictMock<MockAcceptedCallback> mock_accepted_callback_;
|
|
|
|
WebRtc webrtc;
|
|
PeerId self_id("peer_id");
|
|
const std::string service_id("NearbySharing");
|
|
LocationHint location_hint{};
|
|
|
|
ASSERT_TRUE(webrtc.IsAvailable());
|
|
ASSERT_TRUE(webrtc.StartAcceptingConnections(
|
|
service_id, self_id, location_hint,
|
|
{mock_accepted_callback_.AsStdFunction()}));
|
|
EXPECT_FALSE(webrtc.StartAcceptingConnections(
|
|
service_id, self_id, location_hint,
|
|
{mock_accepted_callback_.AsStdFunction()}));
|
|
EXPECT_TRUE(webrtc.IsAcceptingConnections(service_id));
|
|
EXPECT_FALSE(webrtc.IsAcceptingConnections(std::string{}));
|
|
}
|
|
|
|
// Tests the flow when the device tries to connect but the data channel times
|
|
// out.
|
|
TEST_F(WebRtcTest, Connect_DataChannelTimeOut) {
|
|
WebRtc webrtc;
|
|
PeerId peer_id("peer_id");
|
|
const std::string service_id("NearbySharing");
|
|
LocationHint location_hint;
|
|
|
|
ASSERT_TRUE(webrtc.IsAvailable());
|
|
CancellationFlag flag;
|
|
WebRtcSocketWrapper wrapper_1 =
|
|
webrtc.Connect(service_id, peer_id, location_hint, &flag);
|
|
EXPECT_FALSE(wrapper_1.IsValid());
|
|
|
|
EXPECT_TRUE(webrtc.StartAcceptingConnections(
|
|
service_id, peer_id, location_hint, AcceptedConnectionCallback()));
|
|
}
|
|
|
|
// Tests the flow when the device calls Connect() after calling
|
|
// StartAcceptingConnections() without StopAcceptingConnections().
|
|
TEST_F(WebRtcTest, StartAcceptingConnection_ThenConnect) {
|
|
using MockAcceptedCallback =
|
|
testing::MockFunction<void(WebRtcSocketWrapper socket)>;
|
|
testing::StrictMock<MockAcceptedCallback> mock_accepted_callback_;
|
|
|
|
WebRtc webrtc;
|
|
PeerId self_id("peer_id");
|
|
const std::string service_id("NearbySharing");
|
|
LocationHint location_hint;
|
|
|
|
ASSERT_TRUE(webrtc.IsAvailable());
|
|
ASSERT_TRUE(webrtc.StartAcceptingConnections(
|
|
service_id, self_id, location_hint,
|
|
{mock_accepted_callback_.AsStdFunction()}));
|
|
CancellationFlag flag;
|
|
WebRtcSocketWrapper wrapper = webrtc.Connect(
|
|
service_id, PeerId("random_peer_id"), location_hint, &flag);
|
|
EXPECT_TRUE(webrtc.IsAcceptingConnections(service_id));
|
|
EXPECT_FALSE(wrapper.IsValid());
|
|
EXPECT_FALSE(webrtc.StartAcceptingConnections(
|
|
service_id, self_id, location_hint,
|
|
{mock_accepted_callback_.AsStdFunction()}));
|
|
}
|
|
|
|
// Tests the flow when the device calls StartAcceptingConnections but the medium
|
|
// is closed before a peer device can connect to it.
|
|
TEST_F(WebRtcTest, StartAndStopAcceptingConnections) {
|
|
using MockAcceptedCallback =
|
|
testing::MockFunction<void(WebRtcSocketWrapper socket)>;
|
|
testing::StrictMock<MockAcceptedCallback> mock_accepted_callback_;
|
|
|
|
WebRtc webrtc;
|
|
PeerId self_id("peer_id");
|
|
const std::string service_id("NearbySharing");
|
|
LocationHint location_hint;
|
|
|
|
ASSERT_TRUE(webrtc.IsAvailable());
|
|
ASSERT_TRUE(webrtc.StartAcceptingConnections(
|
|
service_id, self_id, location_hint,
|
|
{mock_accepted_callback_.AsStdFunction()}));
|
|
EXPECT_TRUE(webrtc.IsAcceptingConnections(service_id));
|
|
webrtc.StopAcceptingConnections(service_id);
|
|
EXPECT_FALSE(webrtc.IsAcceptingConnections(service_id));
|
|
}
|
|
|
|
// Tests the flow when the device tries to connect to two different peers
|
|
// without disconnecting in between.
|
|
TEST_F(WebRtcTest, ConnectTwice) {
|
|
WebRtc receiver, sender, device_c;
|
|
WebRtcSocketWrapper receiver_socket, sender_socket;
|
|
const PeerId self_id("self_id"), other_id("other_id");
|
|
const std::string service_id("NearbySharing");
|
|
LocationHint location_hint;
|
|
Future<bool> connected;
|
|
ByteArray message("message xyz");
|
|
|
|
receiver.StartAcceptingConnections(
|
|
service_id, self_id, location_hint,
|
|
{[&receiver_socket, connected](WebRtcSocketWrapper wrapper) mutable {
|
|
receiver_socket = wrapper;
|
|
connected.Set(receiver_socket.IsValid());
|
|
}});
|
|
|
|
device_c.StartAcceptingConnections(service_id, other_id, location_hint,
|
|
{[](WebRtcSocketWrapper wrapper) {}});
|
|
|
|
CancellationFlag flag;
|
|
sender_socket = sender.Connect(service_id, self_id, location_hint, &flag);
|
|
EXPECT_TRUE(sender_socket.IsValid());
|
|
|
|
ExceptionOr<bool> devices_connected = connected.Get();
|
|
ASSERT_TRUE(devices_connected.ok());
|
|
EXPECT_TRUE(devices_connected.result());
|
|
|
|
WebRtcSocketWrapper socket =
|
|
sender.Connect(service_id, other_id, location_hint, &flag);
|
|
EXPECT_TRUE(socket.IsValid());
|
|
socket.Close();
|
|
|
|
EXPECT_TRUE(receiver_socket.IsValid());
|
|
EXPECT_TRUE(sender_socket.IsValid());
|
|
|
|
sender_socket.GetOutputStream().Write(message);
|
|
ExceptionOr<ByteArray> received_msg =
|
|
receiver_socket.GetInputStream().Read(/*size=*/32);
|
|
ASSERT_TRUE(received_msg.ok());
|
|
EXPECT_EQ(message, received_msg.result());
|
|
|
|
receiver_socket.Close();
|
|
}
|
|
|
|
// Tests the flow when the two devices exchange SDP messages and connect to each
|
|
// other but disconnect before being able to send/receive the actual data.
|
|
TEST_F(WebRtcTest, ConnectBothDevicesAndAbort) {
|
|
WebRtc receiver, sender;
|
|
WebRtcSocketWrapper receiver_socket, sender_socket;
|
|
const PeerId self_id("self_id");
|
|
const std::string service_id("NearbySharing");
|
|
LocationHint location_hint;
|
|
Future<bool> connected;
|
|
ByteArray message("message xyz");
|
|
|
|
receiver.StartAcceptingConnections(
|
|
service_id, self_id, location_hint,
|
|
{[&receiver_socket, connected](WebRtcSocketWrapper wrapper) mutable {
|
|
receiver_socket = wrapper;
|
|
connected.Set(receiver_socket.IsValid());
|
|
}});
|
|
|
|
CancellationFlag flag;
|
|
sender_socket = sender.Connect(service_id, self_id, location_hint, &flag);
|
|
EXPECT_TRUE(sender_socket.IsValid());
|
|
|
|
ExceptionOr<bool> devices_connected = connected.Get();
|
|
ASSERT_TRUE(devices_connected.ok());
|
|
EXPECT_TRUE(devices_connected.result());
|
|
|
|
receiver_socket.Close();
|
|
}
|
|
|
|
// Tests the flow when the two devices exchange SDP messages and connect to each
|
|
// other and the actual data is exchanged successfully between the devices.
|
|
TEST_F(WebRtcTest, ConnectBothDevicesAndSendData) {
|
|
WebRtc receiver, sender;
|
|
WebRtcSocketWrapper receiver_socket, sender_socket;
|
|
const PeerId self_id("self_id");
|
|
const std::string service_id("NearbySharing");
|
|
LocationHint location_hint;
|
|
Future<bool> connected;
|
|
ByteArray message("message");
|
|
|
|
receiver.StartAcceptingConnections(
|
|
service_id, self_id, location_hint,
|
|
{[&receiver_socket, connected](WebRtcSocketWrapper wrapper) mutable {
|
|
receiver_socket = wrapper;
|
|
connected.Set(receiver_socket.IsValid());
|
|
}});
|
|
|
|
CancellationFlag flag;
|
|
sender_socket = sender.Connect(service_id, self_id, location_hint, &flag);
|
|
EXPECT_TRUE(sender_socket.IsValid());
|
|
|
|
ExceptionOr<bool> devices_connected = connected.Get();
|
|
ASSERT_TRUE(devices_connected.ok());
|
|
EXPECT_TRUE(devices_connected.result());
|
|
|
|
sender_socket.GetOutputStream().Write(message);
|
|
ExceptionOr<ByteArray> received_msg =
|
|
receiver_socket.GetInputStream().Read(/*size=*/32);
|
|
ASSERT_TRUE(received_msg.ok());
|
|
EXPECT_EQ(message, received_msg.result());
|
|
|
|
receiver_socket.Close();
|
|
}
|
|
|
|
// Tests the flow when the two devices exchange SDP messages and connect to each
|
|
// other but the signaling channel is closed before sending the data.
|
|
TEST_F(WebRtcTest, ConnectBothDevices_ShutdownSignaling_SendData) {
|
|
WebRtc receiver, sender;
|
|
WebRtcSocketWrapper receiver_socket, sender_socket;
|
|
const PeerId self_id("self_id");
|
|
const std::string service_id("NearbySharing");
|
|
LocationHint location_hint;
|
|
Future<bool> connected;
|
|
ByteArray message("message xyz");
|
|
|
|
receiver.StartAcceptingConnections(
|
|
service_id, self_id, location_hint,
|
|
{[&receiver_socket, connected](WebRtcSocketWrapper wrapper) mutable {
|
|
receiver_socket = wrapper;
|
|
connected.Set(receiver_socket.IsValid());
|
|
}});
|
|
|
|
CancellationFlag flag;
|
|
sender_socket = sender.Connect(service_id, self_id, location_hint, &flag);
|
|
EXPECT_TRUE(sender_socket.IsValid());
|
|
|
|
ExceptionOr<bool> devices_connected = connected.Get();
|
|
ASSERT_TRUE(devices_connected.ok());
|
|
EXPECT_TRUE(devices_connected.result());
|
|
|
|
// Only shuts down signaling channel.
|
|
receiver.StopAcceptingConnections(service_id);
|
|
|
|
sender_socket.GetOutputStream().Write(message);
|
|
ExceptionOr<ByteArray> received_msg =
|
|
receiver_socket.GetInputStream().Read(/*size=*/32);
|
|
ASSERT_TRUE(received_msg.ok());
|
|
EXPECT_EQ(message, received_msg.result());
|
|
}
|
|
|
|
TEST_F(WebRtcTest, Connect_NullPeerConnection) {
|
|
using MockAcceptedCallback =
|
|
testing::MockFunction<void(WebRtcSocketWrapper socket)>;
|
|
testing::StrictMock<MockAcceptedCallback> mock_accepted_callback_;
|
|
|
|
MediumEnvironment::Instance().SetUseValidPeerConnection(
|
|
/*use_valid_peer_connection=*/false);
|
|
|
|
WebRtc webrtc;
|
|
const std::string service_id("NearbySharing");
|
|
PeerId self_id("peer_id");
|
|
LocationHint location_hint;
|
|
|
|
ASSERT_TRUE(webrtc.IsAvailable());
|
|
CancellationFlag flag;
|
|
WebRtcSocketWrapper wrapper = webrtc.Connect(
|
|
service_id, PeerId("random_peer_id"), location_hint, &flag);
|
|
EXPECT_FALSE(wrapper.IsValid());
|
|
}
|
|
|
|
} // namespace
|
|
|
|
} // namespace mediums
|
|
} // namespace connections
|
|
} // namespace nearby
|
|
} // namespace location
|