467 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			467 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			C++
		
	
	
	
| /*
 | |
|  * Copyright (C) 2016 The Android Open Source Project
 | |
|  *
 | |
|  * Licensed under the Apache License, Version 2.0 (the "License");
 | |
|  * you may not use this file except in compliance with the License.
 | |
|  * You may obtain a copy of the License at
 | |
|  *
 | |
|  *      http://www.apache.org/licenses/LICENSE-2.0
 | |
|  *
 | |
|  * Unless required by applicable law or agreed to in writing, software
 | |
|  * distributed under the License is distributed on an "AS IS" BASIS,
 | |
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | |
|  * See the License for the specific language governing permissions and
 | |
|  * limitations under the License.
 | |
|  */
 | |
| 
 | |
| #include "bugreport.h"
 | |
| 
 | |
| #include <gmock/gmock.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::Action;
 | |
| using ::testing::ActionInterface;
 | |
| using ::testing::DoAll;
 | |
| using ::testing::ElementsAre;
 | |
| using ::testing::HasSubstr;
 | |
| using ::testing::MakeAction;
 | |
| using ::testing::Return;
 | |
| using ::testing::StrEq;
 | |
| using ::testing::WithArg;
 | |
| using ::testing::internal::CaptureStderr;
 | |
| using ::testing::internal::CaptureStdout;
 | |
| using ::testing::internal::GetCapturedStderr;
 | |
| using ::testing::internal::GetCapturedStdout;
 | |
| 
 | |
| // Empty function so tests don't need to be linked against file_sync_service.cpp, which requires
 | |
| // SELinux and its transitive dependencies...
 | |
| bool do_sync_pull(const std::vector<const char*>& srcs, const char* dst, bool copy_attrs,
 | |
|                   const char* name) {
 | |
|     ADD_FAILURE() << "do_sync_pull() should have been mocked";
 | |
|     return false;
 | |
| }
 | |
| 
 | |
| // Empty functions so tests don't need to be linked against commandline.cpp
 | |
| DefaultStandardStreamsCallback DEFAULT_STANDARD_STREAMS_CALLBACK(nullptr, nullptr);
 | |
| 
 | |
| int send_shell_command(const std::string& command, bool disable_shell_protocol,
 | |
|                        StandardStreamsCallbackInterface* callback) {
 | |
|     ADD_FAILURE() << "send_shell_command() should have been mocked";
 | |
|     return -42;
 | |
| }
 | |
| 
 | |
| enum StreamType {
 | |
|     kStreamStdout,
 | |
|     kStreamStderr,
 | |
| };
 | |
| 
 | |
| // gmock black magic to provide a WithArg<2>(WriteOnStdout(output)) matcher
 | |
| typedef void OnStandardStreamsCallbackFunction(StandardStreamsCallbackInterface*);
 | |
| 
 | |
| class OnStandardStreamsCallbackAction : public ActionInterface<OnStandardStreamsCallbackFunction> {
 | |
|   public:
 | |
|     explicit OnStandardStreamsCallbackAction(StreamType type, const std::string& output)
 | |
|         : type_(type), output_(output) {
 | |
|     }
 | |
|     virtual Result Perform(const ArgumentTuple& args) {
 | |
|         if (type_ == kStreamStdout) {
 | |
|             ::std::tr1::get<0>(args)->OnStdout(output_.c_str(), output_.size());
 | |
|         }
 | |
|         if (type_ == kStreamStderr) {
 | |
|             ::std::tr1::get<0>(args)->OnStderr(output_.c_str(), output_.size());
 | |
|         }
 | |
|     }
 | |
| 
 | |
|   private:
 | |
|     StreamType type_;
 | |
|     std::string output_;
 | |
| };
 | |
| 
 | |
| // Matcher used to emulated StandardStreamsCallbackInterface.OnStdout(buffer,
 | |
| // length)
 | |
| Action<OnStandardStreamsCallbackFunction> WriteOnStdout(const std::string& output) {
 | |
|     return MakeAction(new OnStandardStreamsCallbackAction(kStreamStdout, output));
 | |
| }
 | |
| 
 | |
| // Matcher used to emulated StandardStreamsCallbackInterface.OnStderr(buffer,
 | |
| // length)
 | |
| Action<OnStandardStreamsCallbackFunction> WriteOnStderr(const std::string& output) {
 | |
|     return MakeAction(new OnStandardStreamsCallbackAction(kStreamStderr, output));
 | |
| }
 | |
| 
 | |
| typedef int CallbackDoneFunction(StandardStreamsCallbackInterface*);
 | |
| 
 | |
| class CallbackDoneAction : public ActionInterface<CallbackDoneFunction> {
 | |
|   public:
 | |
|     explicit CallbackDoneAction(int status) : status_(status) {
 | |
|     }
 | |
|     virtual Result Perform(const ArgumentTuple& args) {
 | |
|         int status = ::std::tr1::get<0>(args)->Done(status_);
 | |
|         return status;
 | |
|     }
 | |
| 
 | |
|   private:
 | |
|     int status_;
 | |
| };
 | |
| 
 | |
| // Matcher used to emulated StandardStreamsCallbackInterface.Done(status)
 | |
| Action<CallbackDoneFunction> ReturnCallbackDone(int status = -1337) {
 | |
|     return MakeAction(new CallbackDoneAction(status));
 | |
| }
 | |
| 
 | |
| class BugreportMock : public Bugreport {
 | |
|   public:
 | |
|     MOCK_METHOD3(SendShellCommand, int(const std::string& command, bool disable_shell_protocol,
 | |
|                                        StandardStreamsCallbackInterface* callback));
 | |
|     MOCK_METHOD4(DoSyncPull, bool(const std::vector<const char*>& srcs, const char* dst,
 | |
|                                   bool copy_attrs, const char* name));
 | |
|     MOCK_METHOD2(UpdateProgress, void(const std::string&, int));
 | |
| };
 | |
| 
 | |
| class BugreportTest : public ::testing::Test {
 | |
|   public:
 | |
|     void SetUp() {
 | |
|         if (!getcwd(&cwd_)) {
 | |
|             ADD_FAILURE() << "getcwd failed: " << strerror(errno);
 | |
|             return;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     void ExpectBugreportzVersion(const std::string& version) {
 | |
|         EXPECT_CALL(br_, SendShellCommand("bugreportz -v", false, _))
 | |
|             .WillOnce(DoAll(WithArg<2>(WriteOnStderr(version)),
 | |
|                             WithArg<2>(ReturnCallbackDone(0))));
 | |
|     }
 | |
| 
 | |
|     void ExpectProgress(int progress_percentage, const std::string& file = "file.zip") {
 | |
|         EXPECT_CALL(br_, UpdateProgress(StrEq("generating " + file), progress_percentage));
 | |
|     }
 | |
| 
 | |
|     BugreportMock br_;
 | |
|     std::string cwd_;  // TODO: make it static
 | |
| };
 | |
| 
 | |
| // Tests when called with invalid number of arguments
 | |
| TEST_F(BugreportTest, InvalidNumberArgs) {
 | |
|     const char* args[] = {"bugreport", "to", "principal"};
 | |
|     ASSERT_EQ(1, br_.DoIt(3, args));
 | |
| }
 | |
| 
 | |
| // Tests the 'adb bugreport' option when the device does not support 'bugreportz' - it falls back
 | |
| // to the flat-file format ('bugreport' binary on device)
 | |
| TEST_F(BugreportTest, NoArgumentsPreNDevice) {
 | |
|     // clang-format off
 | |
|     EXPECT_CALL(br_, SendShellCommand("bugreportz -v", false, _))
 | |
|         .WillOnce(DoAll(WithArg<2>(WriteOnStderr("")),
 | |
|                         // Write some bogus output on stdout to make sure it's ignored
 | |
|                         WithArg<2>(WriteOnStdout("Dude, where is my bugreportz?")),
 | |
|                         WithArg<2>(ReturnCallbackDone(0))));
 | |
|     // clang-format on
 | |
|     std::string bugreport = "Reported the bug was.";
 | |
|     CaptureStdout();
 | |
|     EXPECT_CALL(br_, SendShellCommand("bugreport", false, _))
 | |
|         .WillOnce(DoAll(WithArg<2>(WriteOnStdout(bugreport)), Return(0)));
 | |
| 
 | |
|     const char* args[] = {"bugreport"};
 | |
|     ASSERT_EQ(0, br_.DoIt(1, args));
 | |
|     ASSERT_THAT(GetCapturedStdout(), StrEq(bugreport));
 | |
| }
 | |
| 
 | |
| // Tests the 'adb bugreport' option when the device supports 'bugreportz' version 1.0 - it will
 | |
| // save the bugreport in the current directory with the name provided by the device.
 | |
| TEST_F(BugreportTest, NoArgumentsNDevice) {
 | |
|     ExpectBugreportzVersion("1.0");
 | |
| 
 | |
|     std::string dest_file =
 | |
|         android::base::StringPrintf("%s%cda_bugreport.zip", cwd_.c_str(), OS_PATH_SEPARATOR);
 | |
|     EXPECT_CALL(br_, SendShellCommand("bugreportz", false, _))
 | |
|         .WillOnce(DoAll(WithArg<2>(WriteOnStdout("OK:/device/da_bugreport.zip")),
 | |
|                         WithArg<2>(ReturnCallbackDone())));
 | |
|     EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/da_bugreport.zip")), StrEq(dest_file),
 | |
|                                 false, StrEq("pulling da_bugreport.zip")))
 | |
|         .WillOnce(Return(true));
 | |
| 
 | |
|     const char* args[] = {"bugreport"};
 | |
|     ASSERT_EQ(0, br_.DoIt(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, "da_bugreport.zip");
 | |
|     EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _))
 | |
|         .WillOnce(DoAll(WithArg<2>(WriteOnStdout("BEGIN:/device/da_bugreport.zip\n")),
 | |
|                         WithArg<2>(WriteOnStdout("PROGRESS:50/100\n")),
 | |
|                         WithArg<2>(WriteOnStdout("OK:/device/da_bugreport.zip\n")),
 | |
|                         WithArg<2>(ReturnCallbackDone())));
 | |
|     EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/da_bugreport.zip")), StrEq(dest_file),
 | |
|                                 false, StrEq("pulling da_bugreport.zip")))
 | |
|         .WillOnce(Return(true));
 | |
| 
 | |
|     const char* args[] = {"bugreport"};
 | |
|     ASSERT_EQ(0, br_.DoIt(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("bugreportz", false, _))
 | |
|         .WillOnce(DoAll(WithArg<2>(WriteOnStdout("OK:/device/bugreport.zip")),
 | |
|                         WithArg<2>(ReturnCallbackDone())));
 | |
|     EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
 | |
|                                 false, StrEq("pulling file.zip")))
 | |
|         .WillOnce(Return(true));
 | |
| 
 | |
|     const char* args[] = {"bugreport", "file.zip"};
 | |
|     ASSERT_EQ(0, br_.DoIt(2, args));
 | |
| }
 | |
| 
 | |
| // Tests 'adb bugreport file.zip' when it succeeds but response was sent in
 | |
| // multiple buffer writers and without progress updates.
 | |
| TEST_F(BugreportTest, OkNDeviceSplitBuffer) {
 | |
|     ExpectBugreportzVersion("1.0");
 | |
|     EXPECT_CALL(br_, SendShellCommand("bugreportz", false, _))
 | |
|         .WillOnce(DoAll(WithArg<2>(WriteOnStdout("OK:/device")),
 | |
|                         WithArg<2>(WriteOnStdout("/bugreport.zip")),
 | |
|                         WithArg<2>(ReturnCallbackDone())));
 | |
|     EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
 | |
|                                 false, StrEq("pulling file.zip")))
 | |
|         .WillOnce(Return(true));
 | |
| 
 | |
|     const char* args[] = {"bugreport", "file.zip"};
 | |
|     ASSERT_EQ(0, br_.DoIt(2, args));
 | |
| }
 | |
| 
 | |
| // Tests 'adb bugreport file.zip' when it succeeds and displays progress.
 | |
| TEST_F(BugreportTest, OkProgress) {
 | |
|     ExpectBugreportzVersion("1.1");
 | |
|     ExpectProgress(1);
 | |
|     ExpectProgress(10);
 | |
|     ExpectProgress(50);
 | |
|     ExpectProgress(99);
 | |
|     // clang-format off
 | |
|     EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _))
 | |
|         // NOTE: DoAll accepts at most 10 arguments, and we're almost reached that limit...
 | |
|         .WillOnce(DoAll(
 | |
|             // Name might change on OK, so make sure the right one is picked.
 | |
|             WithArg<2>(WriteOnStdout("BEGIN:/device/bugreport___NOT.zip\n")),
 | |
|             // Progress line in one write
 | |
|             WithArg<2>(WriteOnStdout("PROGRESS:1/100\n")),
 | |
|             // Add some bogus lines
 | |
|             WithArg<2>(WriteOnStdout("\nDUDE:SWEET\n\nBLA\n\nBLA\nBLA\n\n")),
 | |
|             // Multiple progress lines in one write
 | |
|             WithArg<2>(WriteOnStdout("PROGRESS:10/100\nPROGRESS:50/100\n")),
 | |
|             // Progress line in multiple writes
 | |
|             WithArg<2>(WriteOnStdout("PROG")),
 | |
|             WithArg<2>(WriteOnStdout("RESS:99")),
 | |
|             WithArg<2>(WriteOnStdout("/100\n")),
 | |
|             // Split last message as well, just in case
 | |
|             WithArg<2>(WriteOnStdout("OK:/device/bugreport")),
 | |
|             WithArg<2>(WriteOnStdout(".zip")),
 | |
|             WithArg<2>(ReturnCallbackDone())));
 | |
|     // clang-format on
 | |
|     EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
 | |
|                                 false, StrEq("pulling file.zip")))
 | |
|         .WillOnce(Return(true));
 | |
| 
 | |
|     const char* args[] = {"bugreport", "file.zip"};
 | |
|     ASSERT_EQ(0, br_.DoIt(2, args));
 | |
| }
 | |
| 
 | |
| // Tests 'adb bugreport file.zip' when it succeeds and displays progress, even if progress recedes.
 | |
| TEST_F(BugreportTest, OkProgressAlwaysForward) {
 | |
|     ExpectBugreportzVersion("1.1");
 | |
|     ExpectProgress(1);
 | |
|     ExpectProgress(50);
 | |
|     ExpectProgress(75);
 | |
|     // clang-format off
 | |
|     EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _))
 | |
|         // NOTE: DoAll accepts at most 10 arguments, and we're almost reached that limit...
 | |
|         .WillOnce(DoAll(
 | |
|             WithArg<2>(WriteOnStdout("BEGIN:/device/bugreport.zip\n")),
 | |
|             WithArg<2>(WriteOnStdout("PROGRESS:1/100\n")), // 1%
 | |
|             WithArg<2>(WriteOnStdout("PROGRESS:50/100\n")), // 50%
 | |
|             // 25% should be ignored becaused it receded.
 | |
|             WithArg<2>(WriteOnStdout("PROGRESS:25/100\n")), // 25%
 | |
|             WithArg<2>(WriteOnStdout("PROGRESS:75/100\n")), // 75%
 | |
|             // 75% should be ignored becaused it didn't change.
 | |
|             WithArg<2>(WriteOnStdout("PROGRESS:75/100\n")), // 75%
 | |
|             // Try a receeding percentage with a different max progress
 | |
|             WithArg<2>(WriteOnStdout("PROGRESS:700/1000\n")), // 70%
 | |
|             WithArg<2>(WriteOnStdout("OK:/device/bugreport.zip")),
 | |
|             WithArg<2>(ReturnCallbackDone())));
 | |
|     // clang-format on
 | |
|     EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
 | |
|                                 false, StrEq("pulling file.zip")))
 | |
|         .WillOnce(Return(true));
 | |
| 
 | |
|     const char* args[] = {"bugreport", "file.zip"};
 | |
|     ASSERT_EQ(0, br_.DoIt(2, args));
 | |
| }
 | |
| 
 | |
| // Tests 'adb bugreport file.zip' when it succeeds and displays the initial progress of 0%
 | |
| TEST_F(BugreportTest, OkProgressZeroPercentIsNotIgnored) {
 | |
|     ExpectBugreportzVersion("1.1");
 | |
|     ExpectProgress(0);
 | |
|     ExpectProgress(1);
 | |
|     // clang-format off
 | |
|     EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _))
 | |
|         // NOTE: DoAll accepts at most 10 arguments, and we're almost reached that limit...
 | |
|         .WillOnce(DoAll(
 | |
|             WithArg<2>(WriteOnStdout("BEGIN:/device/bugreport.zip\n")),
 | |
|             WithArg<2>(WriteOnStdout("PROGRESS:1/100000\n")),
 | |
|             WithArg<2>(WriteOnStdout("PROGRESS:1/100\n")), // 1%
 | |
|             WithArg<2>(WriteOnStdout("OK:/device/bugreport.zip")),
 | |
|             WithArg<2>(ReturnCallbackDone())));
 | |
|     // clang-format on
 | |
|     EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
 | |
|                                 false, StrEq("pulling file.zip")))
 | |
|         .WillOnce(Return(true));
 | |
| 
 | |
|     const char* args[] = {"bugreport", "file.zip"};
 | |
|     ASSERT_EQ(0, br_.DoIt(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("bugreportz -p", false, _))
 | |
|         .WillOnce(DoAll(WithArg<2>(WriteOnStdout("BEGIN:/device/da_bugreport.zip\n")),
 | |
|                         WithArg<2>(WriteOnStdout("OK:/device/da_bugreport.zip")),
 | |
|                         WithArg<2>(ReturnCallbackDone())));
 | |
|     EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/da_bugreport.zip")), StrEq(dest_file),
 | |
|                                 false, StrEq("pulling da_bugreport.zip")))
 | |
|         .WillOnce(Return(true));
 | |
| 
 | |
|     const char* args[] = {"bugreport", td.path};
 | |
|     ASSERT_EQ(0, br_.DoIt(2, args));
 | |
| }
 | |
| 
 | |
| // Tests 'adb bugreport file' when it succeeds
 | |
| TEST_F(BugreportTest, OkNoExtension) {
 | |
|     ExpectBugreportzVersion("1.1");
 | |
|     EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _))
 | |
|         .WillOnce(DoAll(WithArg<2>(WriteOnStdout("OK:/device/bugreport.zip\n")),
 | |
|                         WithArg<2>(ReturnCallbackDone())));
 | |
|     EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
 | |
|                                 false, StrEq("pulling file.zip")))
 | |
|         .WillOnce(Return(true));
 | |
| 
 | |
|     const char* args[] = {"bugreport", "file"};
 | |
|     ASSERT_EQ(0, br_.DoIt(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("bugreportz", false, _))
 | |
|         .WillOnce(DoAll(WithArg<2>(WriteOnStdout("BEGIN:/device/da_bugreport.zip\n")),
 | |
|                         WithArg<2>(WriteOnStdout("OK:/device/da_bugreport.zip")),
 | |
|                         WithArg<2>(ReturnCallbackDone())));
 | |
|     EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/da_bugreport.zip")), StrEq(dest_file),
 | |
|                                 false, StrEq("pulling da_bugreport.zip")))
 | |
|         .WillOnce(Return(true));
 | |
| 
 | |
|     const char* args[] = {"bugreport", td.path};
 | |
|     ASSERT_EQ(0, br_.DoIt(2, args));
 | |
| }
 | |
| 
 | |
| // Tests 'adb bugreport file.zip' when the bugreport itself failed
 | |
| TEST_F(BugreportTest, BugreportzReturnedFail) {
 | |
|     ExpectBugreportzVersion("1.1");
 | |
|     EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _))
 | |
|         .WillOnce(
 | |
|             DoAll(WithArg<2>(WriteOnStdout("FAIL:D'OH!\n")), WithArg<2>(ReturnCallbackDone())));
 | |
| 
 | |
|     CaptureStderr();
 | |
|     const char* args[] = {"bugreport", "file.zip"};
 | |
|     ASSERT_EQ(-1, br_.DoIt(2, args));
 | |
|     ASSERT_THAT(GetCapturedStderr(), HasSubstr("D'OH!"));
 | |
| }
 | |
| 
 | |
| // Tests 'adb bugreport file.zip' when the bugreport itself failed but response
 | |
| // was sent in
 | |
| // multiple buffer writes
 | |
| TEST_F(BugreportTest, BugreportzReturnedFailSplitBuffer) {
 | |
|     ExpectBugreportzVersion("1.1");
 | |
|     EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _))
 | |
|         .WillOnce(DoAll(WithArg<2>(WriteOnStdout("FAIL")), WithArg<2>(WriteOnStdout(":D'OH!\n")),
 | |
|                         WithArg<2>(ReturnCallbackDone())));
 | |
| 
 | |
|     CaptureStderr();
 | |
|     const char* args[] = {"bugreport", "file.zip"};
 | |
|     ASSERT_EQ(-1, br_.DoIt(2, args));
 | |
|     ASSERT_THAT(GetCapturedStderr(), HasSubstr("D'OH!"));
 | |
| }
 | |
| 
 | |
| // Tests 'adb bugreport file.zip' when the bugreportz returned an unsupported
 | |
| // response.
 | |
| TEST_F(BugreportTest, BugreportzReturnedUnsupported) {
 | |
|     ExpectBugreportzVersion("1.1");
 | |
|     EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _))
 | |
|         .WillOnce(DoAll(WithArg<2>(WriteOnStdout("bugreportz? What am I, a zombie?")),
 | |
|                         WithArg<2>(ReturnCallbackDone())));
 | |
| 
 | |
|     CaptureStderr();
 | |
|     const char* args[] = {"bugreport", "file.zip"};
 | |
|     ASSERT_EQ(-1, br_.DoIt(2, args));
 | |
|     ASSERT_THAT(GetCapturedStderr(), HasSubstr("bugreportz? What am I, a zombie?"));
 | |
| }
 | |
| 
 | |
| // Tests 'adb bugreport file.zip' when the bugreportz -v command failed
 | |
| TEST_F(BugreportTest, BugreportzVersionFailed) {
 | |
|     EXPECT_CALL(br_, SendShellCommand("bugreportz -v", false, _)).WillOnce(Return(666));
 | |
| 
 | |
|     const char* args[] = {"bugreport", "file.zip"};
 | |
|     ASSERT_EQ(666, br_.DoIt(2, args));
 | |
| }
 | |
| 
 | |
| // Tests 'adb bugreport file.zip' when the bugreportz -v returns status 0 but with no output.
 | |
| TEST_F(BugreportTest, BugreportzVersionEmpty) {
 | |
|     ExpectBugreportzVersion("");
 | |
| 
 | |
|     const char* args[] = {"bugreport", "file.zip"};
 | |
|     ASSERT_EQ(-1, br_.DoIt(2, args));
 | |
| }
 | |
| 
 | |
| // Tests 'adb bugreport file.zip' when the main bugreportz command failed
 | |
| TEST_F(BugreportTest, BugreportzFailed) {
 | |
|     ExpectBugreportzVersion("1.1");
 | |
|     EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _)).WillOnce(Return(666));
 | |
| 
 | |
|     const char* args[] = {"bugreport", "file.zip"};
 | |
|     ASSERT_EQ(666, br_.DoIt(2, args));
 | |
| }
 | |
| 
 | |
| // Tests 'adb bugreport file.zip' when the bugreport could not be pulled
 | |
| TEST_F(BugreportTest, PullFails) {
 | |
|     ExpectBugreportzVersion("1.1");
 | |
|     EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _))
 | |
|         .WillOnce(DoAll(WithArg<2>(WriteOnStdout("OK:/device/bugreport.zip")),
 | |
|                         WithArg<2>(ReturnCallbackDone())));
 | |
|     EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
 | |
|                                 false, HasSubstr("file.zip")))
 | |
|         .WillOnce(Return(false));
 | |
| 
 | |
|     const char* args[] = {"bugreport", "file.zip"};
 | |
|     ASSERT_EQ(1, br_.DoIt(2, args));
 | |
| }
 |