blob: cf7a9f346781ec51fa7db8f28b4c499525f64af8 [file] [log] [blame]
// 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::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