mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-14 14:46:12 -04:00
Verify that IO on closed socket returns an error
The test implementation of BluetoothSocket::GetInputStream() would crash if the socket was closed. That's not ideal because the caller can't verify if the socket is open or closed. New test verifies that GetOutputStream() and GetInputStream() always return a valid reference. PiperOrigin-RevId: 518722540
This commit is contained in:
committed by
Copybara-Service
parent
1a78b33a89
commit
adcb341190
@@ -231,6 +231,50 @@ TEST_F(BluetoothClassicMediumTest, SendData) {
|
||||
server_socket.Close();
|
||||
}
|
||||
|
||||
TEST_F(BluetoothClassicMediumTest, IoOnClosedSocketReturnsError) {
|
||||
adapter_a_->SetScanMode(BluetoothAdapter::ScanMode::kConnectable);
|
||||
CountDownLatch found_latch(1);
|
||||
BluetoothDevice* discovered_device = nullptr;
|
||||
bt_a_->StartDiscovery(DiscoveryCallback{
|
||||
.device_discovered_cb =
|
||||
[this, &found_latch, &discovered_device](BluetoothDevice& device) {
|
||||
NEARBY_LOG(INFO, "Device discovered: %s", device.GetName().c_str());
|
||||
EXPECT_EQ(device.GetName(), adapter_b_->GetName());
|
||||
discovered_device = &device;
|
||||
found_latch.CountDown();
|
||||
},
|
||||
});
|
||||
adapter_b_->SetScanMode(BluetoothAdapter::ScanMode::kConnectableDiscoverable);
|
||||
EXPECT_EQ(adapter_b_->GetScanMode(),
|
||||
BluetoothAdapter::ScanMode::kConnectableDiscoverable);
|
||||
ASSERT_TRUE(found_latch.Await().Ok());
|
||||
std::string service_name{"service"};
|
||||
std::string service_uuid("service-uuid");
|
||||
BluetoothServerSocket server_socket =
|
||||
bt_b_->ListenForService(service_name, service_uuid);
|
||||
ASSERT_TRUE(server_socket.IsValid());
|
||||
{
|
||||
ByteArray data("data");
|
||||
CancellationFlag flag;
|
||||
SingleThreadExecutor server_executor;
|
||||
SingleThreadExecutor client_executor;
|
||||
client_executor.Execute([&, this]() {
|
||||
BluetoothSocket socket_a =
|
||||
bt_a_->ConnectToService(*discovered_device, service_uuid, &flag);
|
||||
ASSERT_TRUE(socket_a.IsValid());
|
||||
socket_a.Close();
|
||||
EXPECT_FALSE(socket_a.GetOutputStream().Write(data).Ok());
|
||||
});
|
||||
server_executor.Execute([&]() {
|
||||
BluetoothSocket socket_b = server_socket.Accept();
|
||||
ASSERT_TRUE(socket_b.IsValid());
|
||||
socket_b.Close();
|
||||
EXPECT_FALSE(socket_b.GetInputStream().Read(data.size()).ok());
|
||||
});
|
||||
}
|
||||
server_socket.Close();
|
||||
}
|
||||
|
||||
TEST_F(BluetoothClassicMediumTest, ConstructorDestructorWorks) {
|
||||
// Make sure we can create functional adapters.
|
||||
ASSERT_TRUE(adapter_a_->IsValid());
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "internal/platform/cancellation_flag_listener.h"
|
||||
#include "internal/platform/implementation/bluetooth_classic.h"
|
||||
#include "internal/platform/implementation/g3/bluetooth_adapter.h"
|
||||
#include "internal/platform/input_stream.h"
|
||||
#include "internal/platform/logging.h"
|
||||
#include "internal/platform/medium_environment.h"
|
||||
|
||||
@@ -52,8 +53,11 @@ bool BluetoothSocket::IsConnectedLocked() const { return input_ != nullptr; }
|
||||
|
||||
InputStream& BluetoothSocket::GetInputStream() {
|
||||
auto* remote_socket = GetRemoteSocket();
|
||||
CHECK(remote_socket != nullptr);
|
||||
return remote_socket->GetLocalInputStream();
|
||||
if (remote_socket != nullptr) {
|
||||
return remote_socket->GetLocalInputStream();
|
||||
} else {
|
||||
return invalid_input_stream_;
|
||||
}
|
||||
}
|
||||
|
||||
OutputStream& BluetoothSocket::GetOutputStream() {
|
||||
|
||||
@@ -92,6 +92,19 @@ class BluetoothSocket : public api::BluetoothSocket {
|
||||
// This is a helper for GetOutputStream() method.
|
||||
OutputStream& GetLocalOutputStream() ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
class InvalidInputStream : public InputStream {
|
||||
public:
|
||||
ExceptionOr<ByteArray> Read(std::int64_t size) override {
|
||||
return ExceptionOr<ByteArray>(Exception::kIo);
|
||||
}
|
||||
ExceptionOr<size_t> Skip(size_t offset) override {
|
||||
return ExceptionOr<size_t>(Exception::kIo);
|
||||
}
|
||||
Exception Close() override { return {Exception::kIo}; }
|
||||
};
|
||||
// Returned to the caller if the remote socket is destroyed.
|
||||
InvalidInputStream invalid_input_stream_;
|
||||
|
||||
// Output pipe is initialized by constructor, it remains always valid, until
|
||||
// it is closed. it represents output part of a local socket. Input part of a
|
||||
// local socket comes from the peer socket, after connection.
|
||||
|
||||
Reference in New Issue
Block a user