| // Copyright 2017 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "services/network/udp_socket_test_util.h" |
| |
| #include <utility> |
| |
| #include "base/run_loop.h" |
| #include "base/test/bind_test_util.h" |
| #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace network { |
| |
| namespace test { |
| |
| UDPSocketTestHelper::UDPSocketTestHelper(mojom::UDPSocketPtr* socket) |
| : socket_(socket) {} |
| |
| UDPSocketTestHelper::~UDPSocketTestHelper() {} |
| |
| int UDPSocketTestHelper::ConnectSync(const net::IPEndPoint& remote_addr, |
| mojom::UDPSocketOptionsPtr options, |
| net::IPEndPoint* local_addr_out) { |
| base::RunLoop run_loop; |
| int net_error = net::ERR_FAILED; |
| socket_->get()->Connect( |
| remote_addr, std::move(options), |
| base::BindLambdaForTesting( |
| [&](int result, const base::Optional<net::IPEndPoint>& local_addr) { |
| net_error = result; |
| if (local_addr) { |
| *local_addr_out = local_addr.value(); |
| } |
| run_loop.Quit(); |
| })); |
| run_loop.Run(); |
| return net_error; |
| } |
| |
| int UDPSocketTestHelper::BindSync(const net::IPEndPoint& local_addr, |
| mojom::UDPSocketOptionsPtr options, |
| net::IPEndPoint* local_addr_out) { |
| base::RunLoop run_loop; |
| int net_error = net::ERR_FAILED; |
| socket_->get()->Bind( |
| local_addr, std::move(options), |
| base::BindLambdaForTesting( |
| [&](int result, const base::Optional<net::IPEndPoint>& local_addr) { |
| net_error = result; |
| if (local_addr) { |
| *local_addr_out = local_addr.value(); |
| } |
| run_loop.Quit(); |
| })); |
| run_loop.Run(); |
| return net_error; |
| } |
| |
| int UDPSocketTestHelper::SendToSync(const net::IPEndPoint& remote_addr, |
| const std::vector<uint8_t>& input) { |
| base::RunLoop run_loop; |
| int net_error = net::ERR_FAILED; |
| socket_->get()->SendTo( |
| remote_addr, input, |
| net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS), |
| base::BindLambdaForTesting([&](int result) { |
| net_error = result; |
| run_loop.Quit(); |
| })); |
| run_loop.Run(); |
| return net_error; |
| } |
| |
| int UDPSocketTestHelper::SendSync(const std::vector<uint8_t>& input) { |
| base::RunLoop run_loop; |
| int net_error = net::ERR_FAILED; |
| socket_->get()->Send( |
| input, |
| net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS), |
| base::BindLambdaForTesting([&](int result) { |
| net_error = result; |
| run_loop.Quit(); |
| })); |
| run_loop.Run(); |
| return net_error; |
| } |
| |
| int UDPSocketTestHelper::SetBroadcastSync(bool broadcast) { |
| base::RunLoop run_loop; |
| int net_error = net::ERR_FAILED; |
| socket_->get()->SetBroadcast(broadcast, |
| base::BindLambdaForTesting([&](int result) { |
| net_error = result; |
| run_loop.Quit(); |
| })); |
| run_loop.Run(); |
| return net_error; |
| } |
| |
| int UDPSocketTestHelper::SetSendBufferSizeSync(int send_buffer_size) { |
| base::RunLoop run_loop; |
| int net_error = net::ERR_FAILED; |
| socket_->get()->SetSendBufferSize(send_buffer_size, |
| base::BindLambdaForTesting([&](int result) { |
| net_error = result; |
| run_loop.Quit(); |
| })); |
| run_loop.Run(); |
| return net_error; |
| } |
| |
| int UDPSocketTestHelper::SetReceiveBufferSizeSync(int receive_buffer_size) { |
| base::RunLoop run_loop; |
| int net_error = net::ERR_FAILED; |
| socket_->get()->SetReceiveBufferSize( |
| receive_buffer_size, base::BindLambdaForTesting([&](int result) { |
| net_error = result; |
| run_loop.Quit(); |
| })); |
| run_loop.Run(); |
| return net_error; |
| } |
| |
| int UDPSocketTestHelper::JoinGroupSync(const net::IPAddress& group_address) { |
| base::RunLoop run_loop; |
| int net_error = net::ERR_FAILED; |
| socket_->get()->JoinGroup(group_address, |
| base::BindLambdaForTesting([&](int result) { |
| net_error = result; |
| run_loop.Quit(); |
| })); |
| run_loop.Run(); |
| return net_error; |
| } |
| |
| int UDPSocketTestHelper::LeaveGroupSync(const net::IPAddress& group_address) { |
| base::RunLoop run_loop; |
| int net_error = net::ERR_FAILED; |
| socket_->get()->LeaveGroup(group_address, |
| base::BindLambdaForTesting([&](int result) { |
| net_error = result; |
| run_loop.Quit(); |
| })); |
| run_loop.Run(); |
| return net_error; |
| } |
| |
| UDPSocketReceiverImpl::ReceivedResult::ReceivedResult( |
| int net_error_arg, |
| const base::Optional<net::IPEndPoint>& src_addr_arg, |
| base::Optional<std::vector<uint8_t>> data_arg) |
| : net_error(net_error_arg), |
| src_addr(src_addr_arg), |
| data(std::move(data_arg)) {} |
| |
| UDPSocketReceiverImpl::ReceivedResult::ReceivedResult( |
| const ReceivedResult& other) = default; |
| |
| UDPSocketReceiverImpl::ReceivedResult::~ReceivedResult() {} |
| |
| UDPSocketReceiverImpl::UDPSocketReceiverImpl() |
| : run_loop_(std::make_unique<base::RunLoop>()), |
| expected_receive_count_(0) {} |
| |
| UDPSocketReceiverImpl::~UDPSocketReceiverImpl() {} |
| |
| void UDPSocketReceiverImpl::WaitForReceivedResults(size_t count) { |
| DCHECK_LE(results_.size(), count); |
| DCHECK_EQ(0u, expected_receive_count_); |
| |
| if (results_.size() == count) |
| return; |
| |
| expected_receive_count_ = count; |
| run_loop_->Run(); |
| run_loop_ = std::make_unique<base::RunLoop>(); |
| } |
| |
| void UDPSocketReceiverImpl::OnReceived( |
| int32_t result, |
| const base::Optional<net::IPEndPoint>& src_addr, |
| base::Optional<base::span<const uint8_t>> data) { |
| // OnReceive() API contracts specifies that this method will not be called |
| // with a |result| that is > 0. |
| DCHECK_GE(0, result); |
| DCHECK(result < 0 || data); |
| |
| results_.emplace_back(result, src_addr, |
| data ? base::make_optional(std::vector<uint8_t>( |
| data.value().begin(), data.value().end())) |
| : base::nullopt); |
| if (results_.size() == expected_receive_count_) { |
| expected_receive_count_ = 0; |
| run_loop_->Quit(); |
| } |
| } |
| |
| } // namespace test |
| |
| } // namespace network |