Merge "Allow fuzzy_fastboot test devices over internet" into android10-tests-dev
This commit is contained in:
commit
ea5c4aa4e6
11 changed files with 102 additions and 40 deletions
|
|
@ -297,3 +297,7 @@ int ClientUsbTransport::Close() {
|
||||||
CloseFunctionFs(handle_.get());
|
CloseFunctionFs(handle_.get());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ClientUsbTransport::Reset() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -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_;
|
||||||
|
|
|
||||||
|
|
@ -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",
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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"));
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
@ -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_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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; }
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue