Deprecated 'adb bugreport' with flat files.
am: 307951e124
Change-Id: I909ae170479cba54338b03426bcee123abececc1
This commit is contained in:
commit
617cedac2f
3 changed files with 224 additions and 58 deletions
|
|
@ -14,31 +14,38 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "bugreport.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <android-base/strings.h>
|
#include <android-base/strings.h>
|
||||||
|
|
||||||
#include "bugreport.h"
|
#include "sysdeps.h"
|
||||||
|
#include "adb_utils.h"
|
||||||
#include "file_sync_service.h"
|
#include "file_sync_service.h"
|
||||||
|
|
||||||
static constexpr char BUGZ_OK_PREFIX[] = "OK:";
|
static constexpr char BUGZ_BEGIN_PREFIX[] = "BEGIN:";
|
||||||
static constexpr char BUGZ_FAIL_PREFIX[] = "FAIL:";
|
|
||||||
static constexpr char BUGZ_PROGRESS_PREFIX[] = "PROGRESS:";
|
static constexpr char BUGZ_PROGRESS_PREFIX[] = "PROGRESS:";
|
||||||
static constexpr char BUGZ_PROGRESS_SEPARATOR[] = "/";
|
static constexpr char BUGZ_PROGRESS_SEPARATOR[] = "/";
|
||||||
|
static constexpr char BUGZ_OK_PREFIX[] = "OK:";
|
||||||
|
static constexpr char BUGZ_FAIL_PREFIX[] = "FAIL:";
|
||||||
|
|
||||||
// Custom callback used to handle the output of zipped bugreports.
|
// Custom callback used to handle the output of zipped bugreports.
|
||||||
class BugreportStandardStreamsCallback : public StandardStreamsCallbackInterface {
|
class BugreportStandardStreamsCallback : public StandardStreamsCallbackInterface {
|
||||||
public:
|
public:
|
||||||
BugreportStandardStreamsCallback(const std::string& dest_file, bool show_progress, Bugreport* br)
|
BugreportStandardStreamsCallback(const std::string& dest_dir, const std::string& dest_file,
|
||||||
|
bool show_progress, Bugreport* br)
|
||||||
: br_(br),
|
: br_(br),
|
||||||
src_file_(),
|
src_file_(),
|
||||||
|
dest_dir_(dest_dir),
|
||||||
dest_file_(dest_file),
|
dest_file_(dest_file),
|
||||||
line_message_(android::base::StringPrintf("generating %s", dest_file_.c_str())),
|
line_message_(),
|
||||||
invalid_lines_(),
|
invalid_lines_(),
|
||||||
show_progress_(show_progress),
|
show_progress_(show_progress),
|
||||||
status_(0),
|
status_(0),
|
||||||
line_() {
|
line_() {
|
||||||
|
SetLineMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnStdout(const char* buffer, int length) {
|
void OnStdout(const char* buffer, int length) {
|
||||||
|
|
@ -80,25 +87,49 @@ class BugreportStandardStreamsCallback : public StandardStreamsCallbackInterface
|
||||||
BUGZ_FAIL_PREFIX);
|
BUGZ_FAIL_PREFIX);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
std::string destination;
|
||||||
|
if (dest_dir_.empty()) {
|
||||||
|
destination = dest_file_;
|
||||||
|
} else {
|
||||||
|
destination = android::base::StringPrintf("%s%c%s", dest_dir_.c_str(),
|
||||||
|
OS_PATH_SEPARATOR, dest_file_.c_str());
|
||||||
|
}
|
||||||
std::vector<const char*> srcs{src_file_.c_str()};
|
std::vector<const char*> srcs{src_file_.c_str()};
|
||||||
status_ = br_->DoSyncPull(srcs, dest_file_.c_str(), true, line_message_.c_str()) ? 0 : 1;
|
status_ =
|
||||||
|
br_->DoSyncPull(srcs, destination.c_str(), true, line_message_.c_str()) ? 0 : 1;
|
||||||
if (status_ != 0) {
|
if (status_ != 0) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Bug report finished but could not be copied to '%s'.\n"
|
"Bug report finished but could not be copied to '%s'.\n"
|
||||||
"Try to run 'adb pull %s <directory>'\n"
|
"Try to run 'adb pull %s <directory>'\n"
|
||||||
"to copy it to a directory that can be written.\n",
|
"to copy it to a directory that can be written.\n",
|
||||||
dest_file_.c_str(), src_file_.c_str());
|
destination.c_str(), src_file_.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return status_;
|
return status_;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void SetLineMessage() {
|
||||||
|
line_message_ =
|
||||||
|
android::base::StringPrintf("generating %s", adb_basename(dest_file_).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetSrcFile(const std::string path) {
|
||||||
|
src_file_ = path;
|
||||||
|
if (!dest_dir_.empty()) {
|
||||||
|
// Only uses device-provided name when user passed a directory.
|
||||||
|
dest_file_ = adb_basename(path);
|
||||||
|
SetLineMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ProcessLine(const std::string& line) {
|
void ProcessLine(const std::string& line) {
|
||||||
if (line.empty()) return;
|
if (line.empty()) return;
|
||||||
|
|
||||||
if (android::base::StartsWith(line, BUGZ_OK_PREFIX)) {
|
if (android::base::StartsWith(line, BUGZ_BEGIN_PREFIX)) {
|
||||||
src_file_ = &line[strlen(BUGZ_OK_PREFIX)];
|
SetSrcFile(&line[strlen(BUGZ_BEGIN_PREFIX)]);
|
||||||
|
} else if (android::base::StartsWith(line, BUGZ_OK_PREFIX)) {
|
||||||
|
SetSrcFile(&line[strlen(BUGZ_OK_PREFIX)]);
|
||||||
} else if (android::base::StartsWith(line, BUGZ_FAIL_PREFIX)) {
|
} else if (android::base::StartsWith(line, BUGZ_FAIL_PREFIX)) {
|
||||||
const char* error_message = &line[strlen(BUGZ_FAIL_PREFIX)];
|
const char* error_message = &line[strlen(BUGZ_FAIL_PREFIX)];
|
||||||
fprintf(stderr, "Device failed to take a zipped bugreport: %s\n", error_message);
|
fprintf(stderr, "Device failed to take a zipped bugreport: %s\n", error_message);
|
||||||
|
|
@ -112,22 +143,38 @@ class BugreportStandardStreamsCallback : public StandardStreamsCallbackInterface
|
||||||
size_t idx2 = line.rfind(BUGZ_PROGRESS_SEPARATOR);
|
size_t idx2 = line.rfind(BUGZ_PROGRESS_SEPARATOR);
|
||||||
int progress = std::stoi(line.substr(idx1, (idx2 - idx1)));
|
int progress = std::stoi(line.substr(idx1, (idx2 - idx1)));
|
||||||
int total = std::stoi(line.substr(idx2 + 1));
|
int total = std::stoi(line.substr(idx2 + 1));
|
||||||
br_->UpdateProgress(dest_file_, progress, total);
|
br_->UpdateProgress(line_message_, progress, total);
|
||||||
} else {
|
} else {
|
||||||
invalid_lines_.push_back(line);
|
invalid_lines_.push_back(line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Bugreport* br_;
|
Bugreport* br_;
|
||||||
|
|
||||||
|
// Path of bugreport on device.
|
||||||
std::string src_file_;
|
std::string src_file_;
|
||||||
const std::string dest_file_;
|
|
||||||
const std::string line_message_;
|
// Bugreport destination on host, depending on argument passed on constructor:
|
||||||
|
// - if argument is a directory, dest_dir_ is set with it and dest_file_ will be the name
|
||||||
|
// of the bugreport reported by the device.
|
||||||
|
// - if argument is empty, dest_dir is set as the current directory and dest_file_ will be the
|
||||||
|
// name of the bugreport reported by the device.
|
||||||
|
// - otherwise, dest_dir_ is not set and dest_file_ is set with the value passed on constructor.
|
||||||
|
std::string dest_dir_, dest_file_;
|
||||||
|
|
||||||
|
// Message displayed on LinePrinter, it's updated every time the destination above change.
|
||||||
|
std::string line_message_;
|
||||||
|
|
||||||
|
// Lines sent by bugreportz that contain invalid commands; will be displayed at the end.
|
||||||
std::vector<std::string> invalid_lines_;
|
std::vector<std::string> invalid_lines_;
|
||||||
|
|
||||||
|
// Whether PROGRESS_LINES should be interpreted as progress.
|
||||||
bool show_progress_;
|
bool show_progress_;
|
||||||
|
|
||||||
|
// Overall process of the operation, as returned by Done().
|
||||||
int status_;
|
int status_;
|
||||||
|
|
||||||
// Temporary buffer containing the characters read since the last newline
|
// Temporary buffer containing the characters read since the last newline (\n).
|
||||||
// (\n).
|
|
||||||
std::string line_;
|
std::string line_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(BugreportStandardStreamsCallback);
|
DISALLOW_COPY_AND_ASSIGN(BugreportStandardStreamsCallback);
|
||||||
|
|
@ -137,17 +184,7 @@ class BugreportStandardStreamsCallback : public StandardStreamsCallbackInterface
|
||||||
int usage();
|
int usage();
|
||||||
|
|
||||||
int Bugreport::DoIt(TransportType transport_type, const char* serial, int argc, const char** argv) {
|
int Bugreport::DoIt(TransportType transport_type, const char* serial, int argc, const char** argv) {
|
||||||
if (argc == 1) return SendShellCommand(transport_type, serial, "bugreport", false);
|
if (argc > 2) return usage();
|
||||||
if (argc != 2) return usage();
|
|
||||||
|
|
||||||
// Zipped bugreport option - will call 'bugreportz', which prints the location
|
|
||||||
// of the generated
|
|
||||||
// file, then pull it to the destination file provided by the user.
|
|
||||||
std::string dest_file = argv[1];
|
|
||||||
if (!android::base::EndsWith(argv[1], ".zip")) {
|
|
||||||
// TODO: use a case-insensitive comparison (like EndsWithIgnoreCase
|
|
||||||
dest_file += ".zip";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Gets bugreportz version.
|
// Gets bugreportz version.
|
||||||
std::string bugz_stderr;
|
std::string bugz_stderr;
|
||||||
|
|
@ -156,6 +193,12 @@ int Bugreport::DoIt(TransportType transport_type, const char* serial, int argc,
|
||||||
std::string bugz_version = android::base::Trim(bugz_stderr);
|
std::string bugz_version = android::base::Trim(bugz_stderr);
|
||||||
|
|
||||||
if (status != 0 || bugz_version.empty()) {
|
if (status != 0 || bugz_version.empty()) {
|
||||||
|
// Device does not support bugreportz: if called as 'adb bugreport', just falls out to the
|
||||||
|
// flat-file version
|
||||||
|
if (argc == 1) return SendShellCommand(transport_type, serial, "bugreport", false);
|
||||||
|
|
||||||
|
// But if user explicitly asked for a zipped bug report, fails instead (otherwise calling
|
||||||
|
// 'bugreport' would generate a lot of output the user might not be prepared to handle)
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Failed to get bugreportz version: 'bugreportz -v' returned '%s' (code %d).\n"
|
"Failed to get bugreportz version: 'bugreportz -v' returned '%s' (code %d).\n"
|
||||||
"If the device runs Android M or below, try 'adb bugreport' instead.\n",
|
"If the device runs Android M or below, try 'adb bugreport' instead.\n",
|
||||||
|
|
@ -163,6 +206,33 @@ int Bugreport::DoIt(TransportType transport_type, const char* serial, int argc,
|
||||||
return status != 0 ? status : -1;
|
return status != 0 ? status : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string dest_file, dest_dir;
|
||||||
|
|
||||||
|
if (argc == 1) {
|
||||||
|
// No args - use current directory
|
||||||
|
if (!getcwd(&dest_dir)) {
|
||||||
|
perror("adb: getcwd failed");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Check whether argument is a directory or file
|
||||||
|
if (directory_exists(argv[1])) {
|
||||||
|
dest_dir = argv[1];
|
||||||
|
} else {
|
||||||
|
dest_file = argv[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dest_file.empty()) {
|
||||||
|
// Uses a default value until device provides the proper name
|
||||||
|
dest_file = "bugreport.zip";
|
||||||
|
} else {
|
||||||
|
if (!android::base::EndsWith(dest_file, ".zip")) {
|
||||||
|
// TODO: use a case-insensitive comparison (like EndsWithIgnoreCase
|
||||||
|
dest_file += ".zip";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool show_progress = true;
|
bool show_progress = true;
|
||||||
std::string bugz_command = "bugreportz -p";
|
std::string bugz_command = "bugreportz -p";
|
||||||
if (bugz_version == "1.0") {
|
if (bugz_version == "1.0") {
|
||||||
|
|
@ -175,7 +245,7 @@ int Bugreport::DoIt(TransportType transport_type, const char* serial, int argc,
|
||||||
show_progress = false;
|
show_progress = false;
|
||||||
bugz_command = "bugreportz";
|
bugz_command = "bugreportz";
|
||||||
}
|
}
|
||||||
BugreportStandardStreamsCallback bugz_callback(dest_file, show_progress, this);
|
BugreportStandardStreamsCallback bugz_callback(dest_dir, dest_file, show_progress, this);
|
||||||
return SendShellCommand(transport_type, serial, bugz_command, false, &bugz_callback);
|
return SendShellCommand(transport_type, serial, bugz_command, false, &bugz_callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,12 @@
|
||||||
#include <gmock/gmock.h>
|
#include <gmock/gmock.h>
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
#include <android-base/strings.h>
|
||||||
|
#include <android-base/test_utils.h>
|
||||||
|
|
||||||
|
#include "sysdeps.h"
|
||||||
|
#include "adb_utils.h"
|
||||||
|
|
||||||
using ::testing::_;
|
using ::testing::_;
|
||||||
using ::testing::Action;
|
using ::testing::Action;
|
||||||
using ::testing::ActionInterface;
|
using ::testing::ActionInterface;
|
||||||
|
|
@ -122,28 +128,38 @@ class BugreportMock : public Bugreport {
|
||||||
|
|
||||||
class BugreportTest : public ::testing::Test {
|
class BugreportTest : public ::testing::Test {
|
||||||
public:
|
public:
|
||||||
void SetBugreportzVersion(const std::string& version) {
|
void SetUp() {
|
||||||
|
if (!getcwd(&cwd_)) {
|
||||||
|
ADD_FAILURE() << "getcwd failed: " << strerror(errno);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExpectBugreportzVersion(const std::string& version) {
|
||||||
EXPECT_CALL(br_,
|
EXPECT_CALL(br_,
|
||||||
SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -v", false, _))
|
SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -v", false, _))
|
||||||
.WillOnce(DoAll(WithArg<4>(WriteOnStderr(version.c_str())),
|
.WillOnce(DoAll(WithArg<4>(WriteOnStderr(version.c_str())),
|
||||||
WithArg<4>(ReturnCallbackDone(0))));
|
WithArg<4>(ReturnCallbackDone(0))));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExpectProgress(int progress, int total) {
|
void ExpectProgress(int progress, int total, const std::string& file = "file.zip") {
|
||||||
EXPECT_CALL(br_, UpdateProgress(HasSubstr("file.zip"), progress, total));
|
EXPECT_CALL(br_, UpdateProgress(StrEq("generating " + file), progress, total));
|
||||||
}
|
}
|
||||||
|
|
||||||
BugreportMock br_;
|
BugreportMock br_;
|
||||||
|
std::string cwd_; // TODO: make it static
|
||||||
};
|
};
|
||||||
|
|
||||||
// Tests when called with invalid number of argumnts
|
// Tests when called with invalid number of arguments
|
||||||
TEST_F(BugreportTest, InvalidNumberArgs) {
|
TEST_F(BugreportTest, InvalidNumberArgs) {
|
||||||
const char* args[1024] = {"bugreport", "to", "principal"};
|
const char* args[1024] = {"bugreport", "to", "principal"};
|
||||||
ASSERT_EQ(-42, br_.DoIt(kTransportLocal, "HannibalLecter", 3, args));
|
ASSERT_EQ(-42, br_.DoIt(kTransportLocal, "HannibalLecter", 3, args));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests the legacy 'adb bugreport' option
|
// Tests the 'adb bugreport' option when the device does not support 'bugreportz' - it falls back
|
||||||
TEST_F(BugreportTest, FlatFileFormat) {
|
// to the flat-file format ('bugreport' binary on device)
|
||||||
|
TEST_F(BugreportTest, NoArgumentsPreNDevice) {
|
||||||
|
ExpectBugreportzVersion("");
|
||||||
EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreport", false, _))
|
EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreport", false, _))
|
||||||
.WillOnce(Return(0));
|
.WillOnce(Return(0));
|
||||||
|
|
||||||
|
|
@ -151,15 +167,52 @@ TEST_F(BugreportTest, FlatFileFormat) {
|
||||||
ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 1, args));
|
ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 1, args));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests 'adb bugreport file.zip' when it succeeds and device does not support
|
// Tests the 'adb bugreport' option when the device supports 'bugreportz' version 1.0 - it will
|
||||||
// progress.
|
// save the bugreport in the current directory with the name provided by the device.
|
||||||
TEST_F(BugreportTest, OkLegacy) {
|
TEST_F(BugreportTest, NoArgumentsNDevice) {
|
||||||
SetBugreportzVersion("1.0");
|
ExpectBugreportzVersion("1.0");
|
||||||
|
|
||||||
|
std::string dest_file =
|
||||||
|
android::base::StringPrintf("%s%cda_bugreport.zip", cwd_.c_str(), OS_PATH_SEPARATOR);
|
||||||
|
EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz", false, _))
|
||||||
|
.WillOnce(DoAll(WithArg<4>(WriteOnStdout("OK:/device/da_bugreport.zip")),
|
||||||
|
WithArg<4>(ReturnCallbackDone())));
|
||||||
|
EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/da_bugreport.zip")), StrEq(dest_file),
|
||||||
|
true, StrEq("generating da_bugreport.zip")))
|
||||||
|
.WillOnce(Return(true));
|
||||||
|
|
||||||
|
const char* args[1024] = {"bugreport"};
|
||||||
|
ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 1, args));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests the 'adb bugreport' option when the device supports 'bugreportz' version 1.1 - it will
|
||||||
|
// save the bugreport in the current directory with the name provided by the device.
|
||||||
|
TEST_F(BugreportTest, NoArgumentsPostNDevice) {
|
||||||
|
ExpectBugreportzVersion("1.1");
|
||||||
|
std::string dest_file =
|
||||||
|
android::base::StringPrintf("%s%cda_bugreport.zip", cwd_.c_str(), OS_PATH_SEPARATOR);
|
||||||
|
ExpectProgress(50, 100, "da_bugreport.zip");
|
||||||
|
EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
|
||||||
|
.WillOnce(DoAll(WithArg<4>(WriteOnStdout("BEGIN:/device/da_bugreport.zip\n")),
|
||||||
|
WithArg<4>(WriteOnStdout("PROGRESS:50/100\n")),
|
||||||
|
WithArg<4>(WriteOnStdout("OK:/device/da_bugreport.zip\n")),
|
||||||
|
WithArg<4>(ReturnCallbackDone())));
|
||||||
|
EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/da_bugreport.zip")), StrEq(dest_file),
|
||||||
|
true, StrEq("generating da_bugreport.zip")))
|
||||||
|
.WillOnce(Return(true));
|
||||||
|
|
||||||
|
const char* args[1024] = {"bugreport"};
|
||||||
|
ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 1, args));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests 'adb bugreport file.zip' when it succeeds and device does not support progress.
|
||||||
|
TEST_F(BugreportTest, OkNDevice) {
|
||||||
|
ExpectBugreportzVersion("1.0");
|
||||||
EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz", false, _))
|
EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz", false, _))
|
||||||
.WillOnce(DoAll(WithArg<4>(WriteOnStdout("OK:/device/bugreport.zip")),
|
.WillOnce(DoAll(WithArg<4>(WriteOnStdout("OK:/device/bugreport.zip")),
|
||||||
WithArg<4>(ReturnCallbackDone())));
|
WithArg<4>(ReturnCallbackDone())));
|
||||||
EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
|
EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
|
||||||
true, HasSubstr("file.zip")))
|
true, StrEq("generating file.zip")))
|
||||||
.WillOnce(Return(true));
|
.WillOnce(Return(true));
|
||||||
|
|
||||||
const char* args[1024] = {"bugreport", "file.zip"};
|
const char* args[1024] = {"bugreport", "file.zip"};
|
||||||
|
|
@ -168,14 +221,14 @@ TEST_F(BugreportTest, OkLegacy) {
|
||||||
|
|
||||||
// Tests 'adb bugreport file.zip' when it succeeds but response was sent in
|
// Tests 'adb bugreport file.zip' when it succeeds but response was sent in
|
||||||
// multiple buffer writers and without progress updates.
|
// multiple buffer writers and without progress updates.
|
||||||
TEST_F(BugreportTest, OkLegacySplitBuffer) {
|
TEST_F(BugreportTest, OkNDeviceSplitBuffer) {
|
||||||
SetBugreportzVersion("1.0");
|
ExpectBugreportzVersion("1.0");
|
||||||
EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz", false, _))
|
EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz", false, _))
|
||||||
.WillOnce(DoAll(WithArg<4>(WriteOnStdout("OK:/device")),
|
.WillOnce(DoAll(WithArg<4>(WriteOnStdout("OK:/device")),
|
||||||
WithArg<4>(WriteOnStdout("/bugreport.zip")),
|
WithArg<4>(WriteOnStdout("/bugreport.zip")),
|
||||||
WithArg<4>(ReturnCallbackDone())));
|
WithArg<4>(ReturnCallbackDone())));
|
||||||
EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
|
EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
|
||||||
true, HasSubstr("file.zip")))
|
true, StrEq("generating file.zip")))
|
||||||
.WillOnce(Return(true));
|
.WillOnce(Return(true));
|
||||||
|
|
||||||
const char* args[1024] = {"bugreport", "file.zip"};
|
const char* args[1024] = {"bugreport", "file.zip"};
|
||||||
|
|
@ -183,16 +236,18 @@ TEST_F(BugreportTest, OkLegacySplitBuffer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests 'adb bugreport file.zip' when it succeeds and displays progress.
|
// Tests 'adb bugreport file.zip' when it succeeds and displays progress.
|
||||||
TEST_F(BugreportTest, Ok) {
|
TEST_F(BugreportTest, OkProgress) {
|
||||||
SetBugreportzVersion("1.1");
|
ExpectBugreportzVersion("1.1");
|
||||||
ExpectProgress(1, 100);
|
ExpectProgress(1, 100);
|
||||||
ExpectProgress(10, 100);
|
ExpectProgress(10, 100);
|
||||||
ExpectProgress(50, 100);
|
ExpectProgress(50, 100);
|
||||||
ExpectProgress(99, 100);
|
ExpectProgress(99, 100);
|
||||||
// clang-format off
|
// clang-format off
|
||||||
EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
|
EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
|
||||||
// NOTE: DoAll accepts at most 10 arguments, and we have reached that limit...
|
// NOTE: DoAll accepts at most 10 arguments, and we're almost reached that limit...
|
||||||
.WillOnce(DoAll(
|
.WillOnce(DoAll(
|
||||||
|
// Name might change on OK, so make sure the right one is picked.
|
||||||
|
WithArg<4>(WriteOnStdout("BEGIN:/device/bugreport___NOT.zip\n")),
|
||||||
// Progress line in one write
|
// Progress line in one write
|
||||||
WithArg<4>(WriteOnStdout("PROGRESS:1/100\n")),
|
WithArg<4>(WriteOnStdout("PROGRESS:1/100\n")),
|
||||||
// Add some bogus lines
|
// Add some bogus lines
|
||||||
|
|
@ -209,30 +264,68 @@ TEST_F(BugreportTest, Ok) {
|
||||||
WithArg<4>(ReturnCallbackDone())));
|
WithArg<4>(ReturnCallbackDone())));
|
||||||
// clang-format on
|
// clang-format on
|
||||||
EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
|
EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
|
||||||
true, HasSubstr("file.zip")))
|
true, StrEq("generating file.zip")))
|
||||||
.WillOnce(Return(true));
|
.WillOnce(Return(true));
|
||||||
|
|
||||||
const char* args[1024] = {"bugreport", "file.zip"};
|
const char* args[1024] = {"bugreport", "file.zip"};
|
||||||
ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
|
ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tests 'adb bugreport dir' when it succeeds and destination is a directory.
|
||||||
|
TEST_F(BugreportTest, OkDirectory) {
|
||||||
|
ExpectBugreportzVersion("1.1");
|
||||||
|
TemporaryDir td;
|
||||||
|
std::string dest_file =
|
||||||
|
android::base::StringPrintf("%s%cda_bugreport.zip", td.path, OS_PATH_SEPARATOR);
|
||||||
|
|
||||||
|
EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
|
||||||
|
.WillOnce(DoAll(WithArg<4>(WriteOnStdout("BEGIN:/device/da_bugreport.zip\n")),
|
||||||
|
WithArg<4>(WriteOnStdout("OK:/device/da_bugreport.zip")),
|
||||||
|
WithArg<4>(ReturnCallbackDone())));
|
||||||
|
EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/da_bugreport.zip")), StrEq(dest_file),
|
||||||
|
true, StrEq("generating da_bugreport.zip")))
|
||||||
|
.WillOnce(Return(true));
|
||||||
|
|
||||||
|
const char* args[1024] = {"bugreport", td.path};
|
||||||
|
ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
|
||||||
|
}
|
||||||
|
|
||||||
// Tests 'adb bugreport file' when it succeeds
|
// Tests 'adb bugreport file' when it succeeds
|
||||||
TEST_F(BugreportTest, OkNoExtension) {
|
TEST_F(BugreportTest, OkNoExtension) {
|
||||||
SetBugreportzVersion("1.1");
|
ExpectBugreportzVersion("1.1");
|
||||||
EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
|
EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
|
||||||
.WillOnce(DoAll(WithArg<4>(WriteOnStdout("OK:/device/bugreport.zip\n")),
|
.WillOnce(DoAll(WithArg<4>(WriteOnStdout("OK:/device/bugreport.zip\n")),
|
||||||
WithArg<4>(ReturnCallbackDone())));
|
WithArg<4>(ReturnCallbackDone())));
|
||||||
EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
|
EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
|
||||||
true, HasSubstr("file.zip")))
|
true, StrEq("generating file.zip")))
|
||||||
.WillOnce(Return(true));
|
.WillOnce(Return(true));
|
||||||
|
|
||||||
const char* args[1024] = {"bugreport", "file"};
|
const char* args[1024] = {"bugreport", "file"};
|
||||||
ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
|
ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tests 'adb bugreport dir' when it succeeds and destination is a directory and device runs N.
|
||||||
|
TEST_F(BugreportTest, OkNDeviceDirectory) {
|
||||||
|
ExpectBugreportzVersion("1.0");
|
||||||
|
TemporaryDir td;
|
||||||
|
std::string dest_file =
|
||||||
|
android::base::StringPrintf("%s%cda_bugreport.zip", td.path, OS_PATH_SEPARATOR);
|
||||||
|
|
||||||
|
EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz", false, _))
|
||||||
|
.WillOnce(DoAll(WithArg<4>(WriteOnStdout("BEGIN:/device/da_bugreport.zip\n")),
|
||||||
|
WithArg<4>(WriteOnStdout("OK:/device/da_bugreport.zip")),
|
||||||
|
WithArg<4>(ReturnCallbackDone())));
|
||||||
|
EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/da_bugreport.zip")), StrEq(dest_file),
|
||||||
|
true, StrEq("generating da_bugreport.zip")))
|
||||||
|
.WillOnce(Return(true));
|
||||||
|
|
||||||
|
const char* args[1024] = {"bugreport", td.path};
|
||||||
|
ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
|
||||||
|
}
|
||||||
|
|
||||||
// Tests 'adb bugreport file.zip' when the bugreport itself failed
|
// Tests 'adb bugreport file.zip' when the bugreport itself failed
|
||||||
TEST_F(BugreportTest, BugreportzReturnedFail) {
|
TEST_F(BugreportTest, BugreportzReturnedFail) {
|
||||||
SetBugreportzVersion("1.1");
|
ExpectBugreportzVersion("1.1");
|
||||||
EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
|
EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
|
||||||
.WillOnce(
|
.WillOnce(
|
||||||
DoAll(WithArg<4>(WriteOnStdout("FAIL:D'OH!\n")), WithArg<4>(ReturnCallbackDone())));
|
DoAll(WithArg<4>(WriteOnStdout("FAIL:D'OH!\n")), WithArg<4>(ReturnCallbackDone())));
|
||||||
|
|
@ -247,7 +340,7 @@ TEST_F(BugreportTest, BugreportzReturnedFail) {
|
||||||
// was sent in
|
// was sent in
|
||||||
// multiple buffer writes
|
// multiple buffer writes
|
||||||
TEST_F(BugreportTest, BugreportzReturnedFailSplitBuffer) {
|
TEST_F(BugreportTest, BugreportzReturnedFailSplitBuffer) {
|
||||||
SetBugreportzVersion("1.1");
|
ExpectBugreportzVersion("1.1");
|
||||||
EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
|
EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
|
||||||
.WillOnce(DoAll(WithArg<4>(WriteOnStdout("FAIL")), WithArg<4>(WriteOnStdout(":D'OH!\n")),
|
.WillOnce(DoAll(WithArg<4>(WriteOnStdout("FAIL")), WithArg<4>(WriteOnStdout(":D'OH!\n")),
|
||||||
WithArg<4>(ReturnCallbackDone())));
|
WithArg<4>(ReturnCallbackDone())));
|
||||||
|
|
@ -261,7 +354,7 @@ TEST_F(BugreportTest, BugreportzReturnedFailSplitBuffer) {
|
||||||
// Tests 'adb bugreport file.zip' when the bugreportz returned an unsupported
|
// Tests 'adb bugreport file.zip' when the bugreportz returned an unsupported
|
||||||
// response.
|
// response.
|
||||||
TEST_F(BugreportTest, BugreportzReturnedUnsupported) {
|
TEST_F(BugreportTest, BugreportzReturnedUnsupported) {
|
||||||
SetBugreportzVersion("1.1");
|
ExpectBugreportzVersion("1.1");
|
||||||
EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
|
EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
|
||||||
.WillOnce(DoAll(WithArg<4>(WriteOnStdout("bugreportz? What am I, a zombie?")),
|
.WillOnce(DoAll(WithArg<4>(WriteOnStdout("bugreportz? What am I, a zombie?")),
|
||||||
WithArg<4>(ReturnCallbackDone())));
|
WithArg<4>(ReturnCallbackDone())));
|
||||||
|
|
@ -283,7 +376,7 @@ TEST_F(BugreportTest, BugreportzVersionFailed) {
|
||||||
|
|
||||||
// Tests 'adb bugreport file.zip' when the bugreportz -v returns status 0 but with no output.
|
// Tests 'adb bugreport file.zip' when the bugreportz -v returns status 0 but with no output.
|
||||||
TEST_F(BugreportTest, BugreportzVersionEmpty) {
|
TEST_F(BugreportTest, BugreportzVersionEmpty) {
|
||||||
SetBugreportzVersion("");
|
ExpectBugreportzVersion("");
|
||||||
|
|
||||||
const char* args[1024] = {"bugreport", "file.zip"};
|
const char* args[1024] = {"bugreport", "file.zip"};
|
||||||
ASSERT_EQ(-1, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
|
ASSERT_EQ(-1, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
|
||||||
|
|
@ -291,7 +384,7 @@ TEST_F(BugreportTest, BugreportzVersionEmpty) {
|
||||||
|
|
||||||
// Tests 'adb bugreport file.zip' when the main bugreportz command failed
|
// Tests 'adb bugreport file.zip' when the main bugreportz command failed
|
||||||
TEST_F(BugreportTest, BugreportzFailed) {
|
TEST_F(BugreportTest, BugreportzFailed) {
|
||||||
SetBugreportzVersion("1.1");
|
ExpectBugreportzVersion("1.1");
|
||||||
EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
|
EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
|
||||||
.WillOnce(Return(666));
|
.WillOnce(Return(666));
|
||||||
|
|
||||||
|
|
@ -301,7 +394,7 @@ TEST_F(BugreportTest, BugreportzFailed) {
|
||||||
|
|
||||||
// Tests 'adb bugreport file.zip' when the bugreport could not be pulled
|
// Tests 'adb bugreport file.zip' when the bugreport could not be pulled
|
||||||
TEST_F(BugreportTest, PullFails) {
|
TEST_F(BugreportTest, PullFails) {
|
||||||
SetBugreportzVersion("1.1");
|
ExpectBugreportzVersion("1.1");
|
||||||
EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
|
EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
|
||||||
.WillOnce(DoAll(WithArg<4>(WriteOnStdout("OK:/device/bugreport.zip")),
|
.WillOnce(DoAll(WithArg<4>(WriteOnStdout("OK:/device/bugreport.zip")),
|
||||||
WithArg<4>(ReturnCallbackDone())));
|
WithArg<4>(ReturnCallbackDone())));
|
||||||
|
|
|
||||||
|
|
@ -81,6 +81,7 @@ static std::string product_file(const char *extra) {
|
||||||
|
|
||||||
static void help() {
|
static void help() {
|
||||||
fprintf(stderr, "%s\n", adb_version().c_str());
|
fprintf(stderr, "%s\n", adb_version().c_str());
|
||||||
|
// clang-format off
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
" -a - directs adb to listen on all interfaces for a connection\n"
|
" -a - directs adb to listen on all interfaces for a connection\n"
|
||||||
" -d - directs command to the only connected USB device\n"
|
" -d - directs command to the only connected USB device\n"
|
||||||
|
|
@ -173,9 +174,11 @@ static void help() {
|
||||||
" (-g: grant all runtime permissions)\n"
|
" (-g: grant all runtime permissions)\n"
|
||||||
" adb uninstall [-k] <package> - remove this app package from the device\n"
|
" adb uninstall [-k] <package> - remove this app package from the device\n"
|
||||||
" ('-k' means keep the data and cache directories)\n"
|
" ('-k' means keep the data and cache directories)\n"
|
||||||
" adb bugreport [<zip_file>] - return all information from the device\n"
|
" adb bugreport [<path>] - return all information from the device that should be included in a zipped bug report.\n"
|
||||||
" that should be included in a bug report.\n"
|
" If <path> is a file, the bug report will be saved as that file.\n"
|
||||||
"\n"
|
" If <path> is a directory, the bug report will be saved in that directory with the name provided by the device.\n"
|
||||||
|
" If <path> is omitted, the bug report will be saved in the current directory with the name provided by the device.\n"
|
||||||
|
" NOTE: if the device does not support zipped bug reports, the bug report will be output on stdout.\n"
|
||||||
" adb backup [-f <file>] [-apk|-noapk] [-obb|-noobb] [-shared|-noshared] [-all] [-system|-nosystem] [<packages...>]\n"
|
" adb backup [-f <file>] [-apk|-noapk] [-obb|-noobb] [-shared|-noshared] [-all] [-system|-nosystem] [<packages...>]\n"
|
||||||
" - write an archive of the device's data to <file>.\n"
|
" - write an archive of the device's data to <file>.\n"
|
||||||
" If no -f option is supplied then the data is written\n"
|
" If no -f option is supplied then the data is written\n"
|
||||||
|
|
@ -249,8 +252,8 @@ static void help() {
|
||||||
" ADB_TRACE - Print debug information. A comma separated list of the following values\n"
|
" ADB_TRACE - Print debug information. A comma separated list of the following values\n"
|
||||||
" 1 or all, adb, sockets, packets, rwx, usb, sync, sysdeps, transport, jdwp\n"
|
" 1 or all, adb, sockets, packets, rwx, usb, sync, sysdeps, transport, jdwp\n"
|
||||||
" ANDROID_SERIAL - The serial number to connect to. -s takes priority over this if given.\n"
|
" ANDROID_SERIAL - The serial number to connect to. -s takes priority over this if given.\n"
|
||||||
" ANDROID_LOG_TAGS - When used with the logcat option, only these debug tags are printed.\n"
|
" ANDROID_LOG_TAGS - When used with the logcat option, only these debug tags are printed.\n");
|
||||||
);
|
// clang-format on
|
||||||
}
|
}
|
||||||
|
|
||||||
int usage() {
|
int usage() {
|
||||||
|
|
@ -1327,7 +1330,7 @@ static std::string find_product_out_path(const std::string& hint) {
|
||||||
if (hint.find_first_of(OS_PATH_SEPARATORS) != std::string::npos) {
|
if (hint.find_first_of(OS_PATH_SEPARATORS) != std::string::npos) {
|
||||||
std::string cwd;
|
std::string cwd;
|
||||||
if (!getcwd(&cwd)) {
|
if (!getcwd(&cwd)) {
|
||||||
fprintf(stderr, "adb: getcwd failed: %s\n", strerror(errno));
|
perror("adb: getcwd failed");
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
return android::base::StringPrintf("%s%c%s", cwd.c_str(), OS_PATH_SEPARATOR, hint.c_str());
|
return android::base::StringPrintf("%s%c%s", cwd.c_str(), OS_PATH_SEPARATOR, hint.c_str());
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue