Merge "Allow fuzzy_fastboot test devices over internet" into android10-tests-dev

This commit is contained in:
Treehugger Robot 2020-01-24 18:07:46 +00:00 committed by Gerrit Code Review
commit ea5c4aa4e6
11 changed files with 102 additions and 40 deletions

View file

@ -297,3 +297,7 @@ int ClientUsbTransport::Close() {
CloseFunctionFs(handle_.get()); CloseFunctionFs(handle_.get());
return 0; return 0;
} }
int ClientUsbTransport::Reset() {
return 0;
}

View file

@ -29,6 +29,7 @@ class ClientUsbTransport : public Transport {
ssize_t Read(void* data, size_t len) override; ssize_t Read(void* data, size_t len) override;
ssize_t Write(const void* data, size_t len) override; ssize_t Write(const void* data, size_t len) override;
int Close() override; int Close() override;
int Reset() override;
private: private:
std::unique_ptr<usb_handle> handle_; std::unique_ptr<usb_handle> handle_;

View file

@ -5,7 +5,7 @@ cc_test_host {
srcs: [ srcs: [
"main.cpp", "main.cpp",
"extensions.cpp", "extensions.cpp",
"usb_transport_sniffer.cpp", "transport_sniffer.cpp",
"fixtures.cpp", "fixtures.cpp",
"test_utils.cpp", "test_utils.cpp",
], ],

View file

@ -48,12 +48,13 @@
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include "fastboot_driver.h" #include "fastboot_driver.h"
#include "tcp.h"
#include "usb.h" #include "usb.h"
#include "extensions.h" #include "extensions.h"
#include "fixtures.h" #include "fixtures.h"
#include "test_utils.h" #include "test_utils.h"
#include "usb_transport_sniffer.h" #include "transport_sniffer.h"
using namespace std::literals::chrono_literals; using namespace std::literals::chrono_literals;
@ -74,7 +75,14 @@ int FastBootTest::MatchFastboot(usb_ifc_info* info, const std::string& local_ser
return 0; return 0;
} }
bool FastBootTest::IsFastbootOverTcp() {
// serial contains ":" is treated as host ip and port number
return (device_serial.find(":") != std::string::npos);
}
bool FastBootTest::UsbStillAvailible() { bool FastBootTest::UsbStillAvailible() {
if (IsFastbootOverTcp()) return true;
// For some reason someone decided to prefix the path with "usb:" // For some reason someone decided to prefix the path with "usb:"
std::string prefix("usb:"); std::string prefix("usb:");
if (std::equal(prefix.begin(), prefix.end(), device_path.begin())) { if (std::equal(prefix.begin(), prefix.end(), device_path.begin())) {
@ -113,15 +121,19 @@ void FastBootTest::SetUp() {
ASSERT_TRUE(UsbStillAvailible()); // The device disconnected ASSERT_TRUE(UsbStillAvailible()); // The device disconnected
} }
const auto matcher = [](usb_ifc_info* info) -> int { if (IsFastbootOverTcp()) {
return MatchFastboot(info, device_serial); ConnectTcpFastbootDevice();
}; } else {
for (int i = 0; i < MAX_USB_TRIES && !transport; i++) { const auto matcher = [](usb_ifc_info* info) -> int {
std::unique_ptr<UsbTransport> usb(usb_open(matcher, USB_TIMEOUT)); return MatchFastboot(info, device_serial);
if (usb) };
transport = std::unique_ptr<UsbTransportSniffer>( for (int i = 0; i < MAX_USB_TRIES && !transport; i++) {
new UsbTransportSniffer(std::move(usb), serial_port)); std::unique_ptr<UsbTransport> usb(usb_open(matcher, USB_TIMEOUT));
std::this_thread::sleep_for(std::chrono::milliseconds(10)); if (usb)
transport = std::unique_ptr<TransportSniffer>(
new TransportSniffer(std::move(usb), serial_port));
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
} }
ASSERT_TRUE(transport); // no nullptr ASSERT_TRUE(transport); // no nullptr
@ -154,6 +166,8 @@ void FastBootTest::TearDown() {
// TODO, this should eventually be piped to a file instead of stdout // TODO, this should eventually be piped to a file instead of stdout
void FastBootTest::TearDownSerial() { void FastBootTest::TearDownSerial() {
if (IsFastbootOverTcp()) return;
if (!transport) return; if (!transport) return;
// One last read from serial // One last read from serial
transport->ProcessSerial(); transport->ProcessSerial();
@ -167,9 +181,34 @@ void FastBootTest::TearDownSerial() {
} }
} }
void FastBootTest::ConnectTcpFastbootDevice() {
std::size_t found = device_serial.find(":");
if (found != std::string::npos) {
for (int i = 0; i < MAX_TCP_TRIES && !transport; i++) {
std::string error;
std::unique_ptr<Transport> tcp(
tcp::Connect(device_serial.substr(0, found), tcp::kDefaultPort, &error)
.release());
if (tcp)
transport =
std::unique_ptr<TransportSniffer>(new TransportSniffer(std::move(tcp), 0));
if (transport != nullptr) break;
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
}
}
void FastBootTest::ReconnectFastbootDevice() { void FastBootTest::ReconnectFastbootDevice() {
fb.reset(); fb.reset();
transport.reset(); transport.reset();
if (IsFastbootOverTcp()) {
ConnectTcpFastbootDevice();
device_path = cb_scratch;
fb = std::unique_ptr<FastBootDriver>(new FastBootDriver(transport.get(), {}, true));
return;
}
while (UsbStillAvailible()) while (UsbStillAvailible())
; ;
printf("WAITING FOR DEVICE\n"); printf("WAITING FOR DEVICE\n");
@ -180,8 +219,8 @@ void FastBootTest::ReconnectFastbootDevice() {
while (!transport) { while (!transport) {
std::unique_ptr<UsbTransport> usb(usb_open(matcher, USB_TIMEOUT)); std::unique_ptr<UsbTransport> usb(usb_open(matcher, USB_TIMEOUT));
if (usb) { if (usb) {
transport = std::unique_ptr<UsbTransportSniffer>( transport = std::unique_ptr<TransportSniffer>(
new UsbTransportSniffer(std::move(usb), serial_port)); new TransportSniffer(std::move(usb), serial_port));
} }
std::this_thread::sleep_for(1s); std::this_thread::sleep_for(1s);
} }

View file

@ -31,7 +31,7 @@
#include "fastboot_driver.h" #include "fastboot_driver.h"
#include "extensions.h" #include "extensions.h"
#include "usb_transport_sniffer.h" #include "transport_sniffer.h"
namespace fastboot { namespace fastboot {
@ -45,11 +45,14 @@ class FastBootTest : public testing::Test {
static int serial_port; static int serial_port;
static std::string device_serial; static std::string device_serial;
static constexpr int MAX_USB_TRIES = 10; static constexpr int MAX_USB_TRIES = 10;
static constexpr int MAX_TCP_TRIES = 6000;
static int MatchFastboot(usb_ifc_info* info, const std::string& local_serial = ""); static int MatchFastboot(usb_ifc_info* info, const std::string& local_serial = "");
static bool IsFastbootOverTcp();
bool UsbStillAvailible(); bool UsbStillAvailible();
bool UserSpaceFastboot(); bool UserSpaceFastboot();
void ReconnectFastbootDevice(); void ReconnectFastbootDevice();
void ConnectTcpFastbootDevice();
protected: protected:
RetCode DownloadCommand(uint32_t size, std::string* response = nullptr, RetCode DownloadCommand(uint32_t size, std::string* response = nullptr,
@ -64,7 +67,7 @@ class FastBootTest : public testing::Test {
void TearDownSerial(); void TearDownSerial();
void SetLockState(bool unlock, bool assert_change = true); void SetLockState(bool unlock, bool assert_change = true);
std::unique_ptr<UsbTransportSniffer> transport; std::unique_ptr<TransportSniffer> transport;
std::unique_ptr<FastBootDriver> fb; std::unique_ptr<FastBootDriver> fb;
private: private:

View file

@ -54,7 +54,7 @@
#include "extensions.h" #include "extensions.h"
#include "fixtures.h" #include "fixtures.h"
#include "test_utils.h" #include "test_utils.h"
#include "usb_transport_sniffer.h" #include "transport_sniffer.h"
namespace fastboot { namespace fastboot {
@ -1756,16 +1756,19 @@ int main(int argc, char** argv) {
} }
setbuf(stdout, NULL); // no buffering setbuf(stdout, NULL); // no buffering
printf("<Waiting for Device>\n");
const auto matcher = [](usb_ifc_info* info) -> int { if (!fastboot::FastBootTest::IsFastbootOverTcp()) {
return fastboot::FastBootTest::MatchFastboot(info, fastboot::FastBootTest::device_serial); printf("<Waiting for Device>\n");
}; const auto matcher = [](usb_ifc_info* info) -> int {
Transport* transport = nullptr; return fastboot::FastBootTest::MatchFastboot(info, fastboot::FastBootTest::device_serial);
while (!transport) { };
transport = usb_open(matcher); Transport* transport = nullptr;
std::this_thread::sleep_for(std::chrono::milliseconds(10)); while (!transport) {
transport = usb_open(matcher);
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
transport->Close();
} }
transport->Close();
if (args.find("serial_port") != args.end()) { if (args.find("serial_port") != args.end()) {
fastboot::FastBootTest::serial_port = fastboot::ConfigureSerial(args.at("serial_port")); fastboot::FastBootTest::serial_port = fastboot::ConfigureSerial(args.at("serial_port"));

View file

@ -1,4 +1,4 @@
#include "usb_transport_sniffer.h" #include "transport_sniffer.h"
#include <android-base/stringprintf.h> #include <android-base/stringprintf.h>
#include <sys/select.h> #include <sys/select.h>
#include <sys/time.h> #include <sys/time.h>
@ -8,15 +8,15 @@
namespace fastboot { namespace fastboot {
UsbTransportSniffer::UsbTransportSniffer(std::unique_ptr<UsbTransport> transport, TransportSniffer::TransportSniffer(std::unique_ptr<Transport> transport,
const int serial_fd) const int serial_fd)
: transport_(std::move(transport)), serial_fd_(serial_fd) {} : transport_(std::move(transport)), serial_fd_(serial_fd) {}
UsbTransportSniffer::~UsbTransportSniffer() { TransportSniffer::~TransportSniffer() {
Close(); Close();
} }
ssize_t UsbTransportSniffer::Read(void* data, size_t len) { ssize_t TransportSniffer::Read(void* data, size_t len) {
ProcessSerial(); ProcessSerial();
ssize_t ret = transport_->Read(data, len); ssize_t ret = transport_->Read(data, len);
@ -37,7 +37,7 @@ ssize_t UsbTransportSniffer::Read(void* data, size_t len) {
return ret; return ret;
} }
ssize_t UsbTransportSniffer::Write(const void* data, size_t len) { ssize_t TransportSniffer::Write(const void* data, size_t len) {
ProcessSerial(); ProcessSerial();
size_t ret = transport_->Write(data, len); size_t ret = transport_->Write(data, len);
@ -58,11 +58,11 @@ ssize_t UsbTransportSniffer::Write(const void* data, size_t len) {
return ret; return ret;
} }
int UsbTransportSniffer::Close() { int TransportSniffer::Close() {
return transport_->Close(); return transport_->Close();
} }
int UsbTransportSniffer::Reset() { int TransportSniffer::Reset() {
ProcessSerial(); ProcessSerial();
int ret = transport_->Reset(); int ret = transport_->Reset();
std::vector<char> buf; std::vector<char> buf;
@ -72,7 +72,7 @@ int UsbTransportSniffer::Reset() {
return ret; return ret;
} }
const std::vector<UsbTransportSniffer::Event> UsbTransportSniffer::Transfers() { const std::vector<TransportSniffer::Event> TransportSniffer::Transfers() {
return transfers_; return transfers_;
} }
@ -81,7 +81,7 @@ const std::vector<UsbTransportSniffer::Event> UsbTransportSniffer::Transfers() {
* the failure. This method will look through its log of captured events, and * the failure. This method will look through its log of captured events, and
* create a clean printable string of everything that happened. * create a clean printable string of everything that happened.
*/ */
std::string UsbTransportSniffer::CreateTrace() { std::string TransportSniffer::CreateTrace() {
std::string ret; std::string ret;
const auto no_print = [](char c) -> bool { return !isprint(c); }; const auto no_print = [](char c) -> bool { return !isprint(c); };
@ -158,7 +158,7 @@ std::string UsbTransportSniffer::CreateTrace() {
// This is a quick call to flush any UART logs the device might have sent // This is a quick call to flush any UART logs the device might have sent
// to our internal event log. It will wait up to 10ms for data to appear // to our internal event log. It will wait up to 10ms for data to appear
void UsbTransportSniffer::ProcessSerial() { void TransportSniffer::ProcessSerial() {
if (serial_fd_ <= 0) return; if (serial_fd_ <= 0) return;
fd_set set; fd_set set;

View file

@ -42,12 +42,12 @@ namespace fastboot {
/* A special class for sniffing reads and writes /* A special class for sniffing reads and writes
* *
* A useful debugging tool is to see the raw fastboot transactions going between * A useful debugging tool is to see the raw fastboot transactions going between
* the host and device. This class wraps the UsbTransport class, and snoops and saves * the host and device. This class is a special subclass of Transport that snoops and saves
* all the transactions going on. Additionally, if there is a console serial port * all the transactions going on. Additionally, if there is a console serial port
* from the device, this class can monitor it as well and capture the interleaving of * from the device, this class can monitor it as well and capture the interleaving of
* transport transactions and UART log messages. * transport transactions and UART log messages.
*/ */
class UsbTransportSniffer : public UsbTransport { class TransportSniffer : public Transport {
public: public:
enum EventType { enum EventType {
READ, READ,
@ -67,8 +67,8 @@ class UsbTransportSniffer : public UsbTransport {
const std::vector<char> buf; const std::vector<char> buf;
}; };
UsbTransportSniffer(std::unique_ptr<UsbTransport> transport, const int serial_fd = 0); TransportSniffer(std::unique_ptr<Transport> transport, const int serial_fd = 0);
~UsbTransportSniffer() override; ~TransportSniffer() override;
virtual ssize_t Read(void* data, size_t len) override; virtual ssize_t Read(void* data, size_t len) override;
virtual ssize_t Write(const void* data, size_t len) override; virtual ssize_t Write(const void* data, size_t len) override;
@ -81,7 +81,7 @@ class UsbTransportSniffer : public UsbTransport {
private: private:
std::vector<Event> transfers_; std::vector<Event> transfers_;
std::unique_ptr<UsbTransport> transport_; std::unique_ptr<Transport> transport_;
const int serial_fd_; const int serial_fd_;
}; };

View file

@ -64,6 +64,7 @@ class TcpTransport : public Transport {
ssize_t Read(void* data, size_t length) override; ssize_t Read(void* data, size_t length) override;
ssize_t Write(const void* data, size_t length) override; ssize_t Write(const void* data, size_t length) override;
int Close() override; int Close() override;
int Reset() override;
private: private:
explicit TcpTransport(std::unique_ptr<Socket> sock) : socket_(std::move(sock)) {} explicit TcpTransport(std::unique_ptr<Socket> sock) : socket_(std::move(sock)) {}
@ -178,6 +179,10 @@ int TcpTransport::Close() {
return result; return result;
} }
int TcpTransport::Reset() {
return 0;
}
std::unique_ptr<Transport> Connect(const std::string& hostname, int port, std::string* error) { std::unique_ptr<Transport> Connect(const std::string& hostname, int port, std::string* error) {
return internal::Connect(Socket::NewClient(Socket::Protocol::kTcp, hostname, port, error), return internal::Connect(Socket::NewClient(Socket::Protocol::kTcp, hostname, port, error),
error); error);

View file

@ -36,6 +36,8 @@ class Transport {
// Closes the underlying transport. Returns 0 on success. // Closes the underlying transport. Returns 0 on success.
virtual int Close() = 0; virtual int Close() = 0;
virtual int Reset() = 0;
// Blocks until the transport disconnects. Transports that don't support // Blocks until the transport disconnects. Transports that don't support
// this will return immediately. Returns 0 on success. // this will return immediately. Returns 0 on success.
virtual int WaitForDisconnect() { return 0; } virtual int WaitForDisconnect() { return 0; }

View file

@ -109,6 +109,7 @@ class UdpTransport : public Transport {
ssize_t Read(void* data, size_t length) override; ssize_t Read(void* data, size_t length) override;
ssize_t Write(const void* data, size_t length) override; ssize_t Write(const void* data, size_t length) override;
int Close() override; int Close() override;
int Reset() override;
private: private:
explicit UdpTransport(std::unique_ptr<Socket> socket) : socket_(std::move(socket)) {} explicit UdpTransport(std::unique_ptr<Socket> socket) : socket_(std::move(socket)) {}
@ -370,6 +371,10 @@ int UdpTransport::Close() {
return result; return result;
} }
int UdpTransport::Reset() {
return 0;
}
std::unique_ptr<Transport> Connect(const std::string& hostname, int port, std::string* error) { std::unique_ptr<Transport> Connect(const std::string& hostname, int port, std::string* error) {
return internal::Connect(Socket::NewClient(Socket::Protocol::kUdp, hostname, port, error), return internal::Connect(Socket::NewClient(Socket::Protocol::kUdp, hostname, port, error),
error); error);