forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Migrate extensions UDP socket API tests to a C++ UDP echo server.
In particular, migrate SocketsUdpApiTest.SocketsUdpExtension and SocketApiTest.SocketUDPExtension. This CL introduces a new C++ TestUdpEchoServer class, which echoes back the data it receives over an ephemeral UDP socket, and makes those two tests use it. They had been the only consumers of the SpawnedTestServer's UDP_ECHO mode, so once this lands, that mode can be removed from the test server. The reason for migrating tests off of SpawnedTestServer is that it has been a source of flaky failures and timeouts for years, so everything that can use an in-process C++ server should be doing so. Bug: 492672 Change-Id: Iec532fc94ee9c33c612fca3d9392388b594707e6 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2513787 Reviewed-by: Reilly Grant <reillyg@chromium.org> Commit-Queue: Matt Menke <mmenke@chromium.org> Cr-Commit-Position: refs/heads/master@{#823307}
- Loading branch information
Matt Menke
authored and
Commit Bot
committed
Nov 2, 2020
1 parent
19334e7
commit 3848643
Showing
8 changed files
with
199 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
133 changes: 133 additions & 0 deletions
133
extensions/browser/api/sockets_udp/test_udp_echo_server.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
// Copyright 2020 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 "extensions/browser/api/sockets_udp/test_udp_echo_server.h" | ||
|
||
#include "base/bind.h" | ||
#include "base/logging.h" | ||
#include "base/memory/ref_counted.h" | ||
#include "base/run_loop.h" | ||
#include "base/task/post_task.h" | ||
#include "net/base/host_port_pair.h" | ||
#include "net/base/io_buffer.h" | ||
#include "net/base/ip_address.h" | ||
#include "net/base/ip_endpoint.h" | ||
#include "net/base/net_errors.h" | ||
#include "net/log/net_log_source.h" | ||
#include "net/socket/udp_server_socket.h" | ||
|
||
namespace extensions { | ||
|
||
// Size of UDP buffer. Max allowed read size. | ||
static const size_t kIOBufferSize = 4096; | ||
|
||
class TestUdpEchoServer::Core { | ||
public: | ||
Core() = default; | ||
~Core() = default; | ||
|
||
Core(const Core&) = delete; | ||
Core& operator=(const Core&) = delete; | ||
|
||
void Start(net::HostPortPair* host_port_pair, int* result) { | ||
udp_server_socket_ = std::make_unique<net::UDPServerSocket>( | ||
nullptr /* net_log */, net::NetLogSource()); | ||
io_buffer_ = base::MakeRefCounted<net::IOBufferWithSize>(kIOBufferSize); | ||
|
||
*result = udp_server_socket_->Listen( | ||
net::IPEndPoint(net::IPAddress::IPv4Localhost(), 0 /* port */)); | ||
if (*result != net::OK) { | ||
LOG(ERROR) << "UDP listen failed."; | ||
udp_server_socket_.reset(); | ||
return; | ||
} | ||
|
||
net::IPEndPoint local_address; | ||
*result = udp_server_socket_->GetLocalAddress(&local_address); | ||
if (*result != net::OK) { | ||
LOG(ERROR) << "Failed to get local address."; | ||
udp_server_socket_.reset(); | ||
return; | ||
} | ||
|
||
*host_port_pair = net::HostPortPair::FromIPEndPoint(local_address); | ||
ReadLoop(); | ||
} | ||
|
||
void ReadLoop() { | ||
int result = udp_server_socket_->RecvFrom( | ||
io_buffer_.get(), io_buffer_->size(), &recv_from_address_, | ||
base::BindOnce(&Core::OnReadComplete, base::Unretained(this))); | ||
if (result != net::ERR_IO_PENDING) | ||
OnReadComplete(result); | ||
} | ||
|
||
void OnReadComplete(int result) { | ||
if (result < 0) { | ||
// Consider read errors fatal, to avoid getting into a read error loop. | ||
LOG(ERROR) << "Error reading from socket: " << net::ErrorToString(result); | ||
return; | ||
} | ||
|
||
int send_result = udp_server_socket_->SendTo( | ||
io_buffer_.get(), result, recv_from_address_, | ||
base::BindOnce(&Core::OnSendComplete, base::Unretained(this), result)); | ||
if (send_result != net::ERR_IO_PENDING) | ||
OnSendComplete(result, send_result); | ||
} | ||
|
||
void OnSendComplete(int expected_result, int result) { | ||
// Don't consider write errors to be fatal. | ||
if (result < 0) { | ||
LOG(ERROR) << "Error writing to socket: " << net::ErrorToString(result); | ||
} else if (result != expected_result) { | ||
LOG(ERROR) << "Failed to write entire message. Expected " | ||
<< expected_result << ", but wrote " << result; | ||
} | ||
ReadLoop(); | ||
} | ||
|
||
private: | ||
std::unique_ptr<net::UDPServerSocket> udp_server_socket_; | ||
|
||
scoped_refptr<net::IOBufferWithSize> io_buffer_; | ||
net::IPEndPoint recv_from_address_; | ||
}; | ||
|
||
TestUdpEchoServer::TestUdpEchoServer() = default; | ||
|
||
TestUdpEchoServer::~TestUdpEchoServer() { | ||
if (io_thread_) { | ||
io_thread_->task_runner()->DeleteSoon(FROM_HERE, std::move(core_)); | ||
base::RunLoop run_loop; | ||
io_thread_->task_runner()->PostTask(FROM_HERE, run_loop.QuitClosure()); | ||
run_loop.Run(); | ||
io_thread_.reset(); | ||
} | ||
} | ||
|
||
bool TestUdpEchoServer::Start(net::HostPortPair* host_port_pair) { | ||
DCHECK(!io_thread_); | ||
|
||
core_ = std::make_unique<Core>(); | ||
|
||
base::Thread::Options thread_options; | ||
thread_options.message_pump_type = base::MessagePumpType::IO; | ||
io_thread_ = std::make_unique<base::Thread>("EmbeddedTestServer IO Thread"); | ||
CHECK(io_thread_->StartWithOptions(thread_options)); | ||
CHECK(io_thread_->WaitUntilThreadStarted()); | ||
|
||
base::RunLoop run_loop; | ||
int result = net::ERR_UNEXPECTED; | ||
io_thread_->task_runner()->PostTaskAndReply( | ||
FROM_HERE, | ||
base::BindOnce(&TestUdpEchoServer::Core::Start, | ||
base::Unretained(core_.get()), host_port_pair, &result), | ||
run_loop.QuitClosure()); | ||
run_loop.Run(); | ||
|
||
return result == net::OK; | ||
} | ||
|
||
} // namespace extensions |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
// Copyright 2020 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. | ||
|
||
#ifndef EXTENSIONS_BROWSER_API_SOCKETS_UDP_TEST_UDP_ECHO_SERVER_H_ | ||
#define EXTENSIONS_BROWSER_API_SOCKETS_UDP_TEST_UDP_ECHO_SERVER_H_ | ||
|
||
#include <memory> | ||
|
||
#include "base/compiler_specific.h" | ||
#include "base/threading/thread.h" | ||
#include "net/base/host_port_pair.h" | ||
|
||
namespace net { | ||
class HostPortPair; | ||
} // namespace net | ||
|
||
namespace extensions { | ||
|
||
// Test UDP server that echos back everything it receives. | ||
class TestUdpEchoServer { | ||
public: | ||
TestUdpEchoServer(); | ||
|
||
// Destroying the server shuts it down. | ||
~TestUdpEchoServer(); | ||
|
||
TestUdpEchoServer(const TestUdpEchoServer&) = delete; | ||
TestUdpEchoServer& operator=(const TestUdpEchoServer&) = delete; | ||
|
||
// Starts the echo server, and returns an error on failure. Sets | ||
// |host_port_pair| to the the host and port the server is listening on. | ||
// |host_port_pair| must not be null. Spins the current message loop while | ||
// waiting for the server to start. | ||
bool Start(net::HostPortPair* host_port_pair) WARN_UNUSED_RESULT; | ||
|
||
private: | ||
// Class that does all the work. Created on the test server's thread, but | ||
// otherwise lives an IO thread, where it is also destroyed. | ||
class Core; | ||
|
||
std::unique_ptr<base::Thread> io_thread_; | ||
|
||
std::unique_ptr<Core> core_; | ||
}; | ||
|
||
} // namespace extensions | ||
|
||
#endif // EXTENSIONS_BROWSER_API_SOCKETS_UDP_TEST_UDP_ECHO_SERVER_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters