blob: 72ca59aa7e038bfee31e36a86b71448f8692e0c2 [file] [log] [blame]
Felipe Leme698e0652016-07-19 17:07:22 -07001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "bugreport.h"
18
19#include <gmock/gmock.h>
20#include <gtest/gtest.h>
21
Felipe Lemeb3239722016-07-29 17:57:00 -070022#include <android-base/strings.h>
23#include <android-base/test_utils.h>
24
25#include "sysdeps.h"
26#include "adb_utils.h"
27
Felipe Leme698e0652016-07-19 17:07:22 -070028using ::testing::_;
Felipe Leme0d4f0502016-07-26 12:14:39 -070029using ::testing::Action;
30using ::testing::ActionInterface;
Felipe Leme698e0652016-07-19 17:07:22 -070031using ::testing::DoAll;
32using ::testing::ElementsAre;
33using ::testing::HasSubstr;
Felipe Leme0d4f0502016-07-26 12:14:39 -070034using ::testing::MakeAction;
Felipe Leme698e0652016-07-19 17:07:22 -070035using ::testing::Return;
Felipe Leme698e0652016-07-19 17:07:22 -070036using ::testing::StrEq;
Felipe Leme0d4f0502016-07-26 12:14:39 -070037using ::testing::WithArg;
Felipe Leme698e0652016-07-19 17:07:22 -070038using ::testing::internal::CaptureStderr;
Felipe Lemef33fcb62016-08-04 12:03:06 -070039using ::testing::internal::CaptureStdout;
Felipe Leme698e0652016-07-19 17:07:22 -070040using ::testing::internal::GetCapturedStderr;
Felipe Lemef33fcb62016-08-04 12:03:06 -070041using ::testing::internal::GetCapturedStdout;
Felipe Leme698e0652016-07-19 17:07:22 -070042
Felipe Leme0d4f0502016-07-26 12:14:39 -070043// Empty function so tests don't need to be linked against file_sync_service.cpp, which requires
Felipe Leme698e0652016-07-19 17:07:22 -070044// SELinux and its transitive dependencies...
45bool do_sync_pull(const std::vector<const char*>& srcs, const char* dst, bool copy_attrs,
46 const char* name) {
47 ADD_FAILURE() << "do_sync_pull() should have been mocked";
48 return false;
49}
50
Felipe Leme0d4f0502016-07-26 12:14:39 -070051// Empty functions so tests don't need to be linked against commandline.cpp
52DefaultStandardStreamsCallback DEFAULT_STANDARD_STREAMS_CALLBACK(nullptr, nullptr);
Felipe Lemededcbaa2017-03-20 11:00:11 -070053
Josh Gaob122b172017-08-16 16:57:01 -070054int send_shell_command(const std::string& command, bool disable_shell_protocol,
55 StandardStreamsCallbackInterface* callback) {
Felipe Leme698e0652016-07-19 17:07:22 -070056 ADD_FAILURE() << "send_shell_command() should have been mocked";
57 return -42;
58}
59
Felipe Leme6f5080f2016-07-26 12:23:40 -070060enum StreamType {
61 kStreamStdout,
62 kStreamStderr,
63};
64
Josh Gaob122b172017-08-16 16:57:01 -070065// gmock black magic to provide a WithArg<2>(WriteOnStdout(output)) matcher
Felipe Leme0d4f0502016-07-26 12:14:39 -070066typedef void OnStandardStreamsCallbackFunction(StandardStreamsCallbackInterface*);
67
68class OnStandardStreamsCallbackAction : public ActionInterface<OnStandardStreamsCallbackFunction> {
69 public:
Felipe Leme6f5080f2016-07-26 12:23:40 -070070 explicit OnStandardStreamsCallbackAction(StreamType type, const std::string& output)
71 : type_(type), output_(output) {
Felipe Leme0d4f0502016-07-26 12:14:39 -070072 }
73 virtual Result Perform(const ArgumentTuple& args) {
Felipe Leme6f5080f2016-07-26 12:23:40 -070074 if (type_ == kStreamStdout) {
75 ::std::tr1::get<0>(args)->OnStdout(output_.c_str(), output_.size());
76 }
77 if (type_ == kStreamStderr) {
78 ::std::tr1::get<0>(args)->OnStderr(output_.c_str(), output_.size());
79 }
Felipe Leme0d4f0502016-07-26 12:14:39 -070080 }
81
82 private:
Felipe Leme6f5080f2016-07-26 12:23:40 -070083 StreamType type_;
Felipe Leme0d4f0502016-07-26 12:14:39 -070084 std::string output_;
85};
86
Felipe Leme6f5080f2016-07-26 12:23:40 -070087// Matcher used to emulated StandardStreamsCallbackInterface.OnStdout(buffer,
88// length)
Felipe Leme0d4f0502016-07-26 12:14:39 -070089Action<OnStandardStreamsCallbackFunction> WriteOnStdout(const std::string& output) {
Felipe Leme6f5080f2016-07-26 12:23:40 -070090 return MakeAction(new OnStandardStreamsCallbackAction(kStreamStdout, output));
91}
92
93// Matcher used to emulated StandardStreamsCallbackInterface.OnStderr(buffer,
94// length)
95Action<OnStandardStreamsCallbackFunction> WriteOnStderr(const std::string& output) {
96 return MakeAction(new OnStandardStreamsCallbackAction(kStreamStderr, output));
Felipe Leme0d4f0502016-07-26 12:14:39 -070097}
98
99typedef int CallbackDoneFunction(StandardStreamsCallbackInterface*);
100
101class CallbackDoneAction : public ActionInterface<CallbackDoneFunction> {
102 public:
Felipe Leme6f5080f2016-07-26 12:23:40 -0700103 explicit CallbackDoneAction(int status) : status_(status) {
104 }
Felipe Leme0d4f0502016-07-26 12:14:39 -0700105 virtual Result Perform(const ArgumentTuple& args) {
Felipe Leme6f5080f2016-07-26 12:23:40 -0700106 int status = ::std::tr1::get<0>(args)->Done(status_);
Felipe Leme0d4f0502016-07-26 12:14:39 -0700107 return status;
108 }
Felipe Leme6f5080f2016-07-26 12:23:40 -0700109
110 private:
111 int status_;
Felipe Leme0d4f0502016-07-26 12:14:39 -0700112};
113
Felipe Leme6f5080f2016-07-26 12:23:40 -0700114// Matcher used to emulated StandardStreamsCallbackInterface.Done(status)
115Action<CallbackDoneFunction> ReturnCallbackDone(int status = -1337) {
116 return MakeAction(new CallbackDoneAction(status));
Felipe Leme0d4f0502016-07-26 12:14:39 -0700117}
118
Felipe Leme698e0652016-07-19 17:07:22 -0700119class BugreportMock : public Bugreport {
120 public:
Josh Gaob122b172017-08-16 16:57:01 -0700121 MOCK_METHOD3(SendShellCommand, int(const std::string& command, bool disable_shell_protocol,
122 StandardStreamsCallbackInterface* callback));
Felipe Leme698e0652016-07-19 17:07:22 -0700123 MOCK_METHOD4(DoSyncPull, bool(const std::vector<const char*>& srcs, const char* dst,
124 bool copy_attrs, const char* name));
Felipe Leme4cc03612017-05-02 10:06:33 -0700125 MOCK_METHOD2(UpdateProgress, void(const std::string&, int));
Felipe Leme698e0652016-07-19 17:07:22 -0700126};
127
128class BugreportTest : public ::testing::Test {
129 public:
Felipe Lemeb3239722016-07-29 17:57:00 -0700130 void SetUp() {
131 if (!getcwd(&cwd_)) {
132 ADD_FAILURE() << "getcwd failed: " << strerror(errno);
133 return;
134 }
135 }
136
137 void ExpectBugreportzVersion(const std::string& version) {
Josh Gaob122b172017-08-16 16:57:01 -0700138 EXPECT_CALL(br_, SendShellCommand("bugreportz -v", false, _))
139 .WillOnce(DoAll(WithArg<2>(WriteOnStderr(version.c_str())),
140 WithArg<2>(ReturnCallbackDone(0))));
Felipe Leme6f5080f2016-07-26 12:23:40 -0700141 }
142
Felipe Leme4cc03612017-05-02 10:06:33 -0700143 void ExpectProgress(int progress_percentage, const std::string& file = "file.zip") {
144 EXPECT_CALL(br_, UpdateProgress(StrEq("generating " + file), progress_percentage));
Felipe Leme6f5080f2016-07-26 12:23:40 -0700145 }
146
Felipe Leme698e0652016-07-19 17:07:22 -0700147 BugreportMock br_;
Felipe Lemeb3239722016-07-29 17:57:00 -0700148 std::string cwd_; // TODO: make it static
Felipe Leme698e0652016-07-19 17:07:22 -0700149};
150
Felipe Lemeb3239722016-07-29 17:57:00 -0700151// Tests when called with invalid number of arguments
Felipe Leme698e0652016-07-19 17:07:22 -0700152TEST_F(BugreportTest, InvalidNumberArgs) {
Felipe Lemef33fcb62016-08-04 12:03:06 -0700153 const char* args[] = {"bugreport", "to", "principal"};
Josh Gaob122b172017-08-16 16:57:01 -0700154 ASSERT_EQ(1, br_.DoIt(3, args));
Felipe Leme698e0652016-07-19 17:07:22 -0700155}
156
Felipe Lemeb3239722016-07-29 17:57:00 -0700157// Tests the 'adb bugreport' option when the device does not support 'bugreportz' - it falls back
158// to the flat-file format ('bugreport' binary on device)
159TEST_F(BugreportTest, NoArgumentsPreNDevice) {
Felipe Lemef33fcb62016-08-04 12:03:06 -0700160 // clang-format off
Josh Gaob122b172017-08-16 16:57:01 -0700161 EXPECT_CALL(br_, SendShellCommand("bugreportz -v", false, _))
162 .WillOnce(DoAll(WithArg<2>(WriteOnStderr("")),
Felipe Lemef33fcb62016-08-04 12:03:06 -0700163 // Write some bogus output on stdout to make sure it's ignored
Josh Gaob122b172017-08-16 16:57:01 -0700164 WithArg<2>(WriteOnStdout("Dude, where is my bugreportz?")),
165 WithArg<2>(ReturnCallbackDone(0))));
Felipe Lemef33fcb62016-08-04 12:03:06 -0700166 // clang-format on
167 std::string bugreport = "Reported the bug was.";
168 CaptureStdout();
Josh Gaob122b172017-08-16 16:57:01 -0700169 EXPECT_CALL(br_, SendShellCommand("bugreport", false, _))
170 .WillOnce(DoAll(WithArg<2>(WriteOnStdout(bugreport)), Return(0)));
Felipe Leme698e0652016-07-19 17:07:22 -0700171
Felipe Lemef33fcb62016-08-04 12:03:06 -0700172 const char* args[] = {"bugreport"};
Josh Gaob122b172017-08-16 16:57:01 -0700173 ASSERT_EQ(0, br_.DoIt(1, args));
Felipe Lemef33fcb62016-08-04 12:03:06 -0700174 ASSERT_THAT(GetCapturedStdout(), StrEq(bugreport));
Felipe Leme698e0652016-07-19 17:07:22 -0700175}
176
Felipe Lemeb3239722016-07-29 17:57:00 -0700177// Tests the 'adb bugreport' option when the device supports 'bugreportz' version 1.0 - it will
178// save the bugreport in the current directory with the name provided by the device.
179TEST_F(BugreportTest, NoArgumentsNDevice) {
180 ExpectBugreportzVersion("1.0");
181
182 std::string dest_file =
183 android::base::StringPrintf("%s%cda_bugreport.zip", cwd_.c_str(), OS_PATH_SEPARATOR);
Josh Gaob122b172017-08-16 16:57:01 -0700184 EXPECT_CALL(br_, SendShellCommand("bugreportz", false, _))
185 .WillOnce(DoAll(WithArg<2>(WriteOnStdout("OK:/device/da_bugreport.zip")),
186 WithArg<2>(ReturnCallbackDone())));
Felipe Lemeb3239722016-07-29 17:57:00 -0700187 EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/da_bugreport.zip")), StrEq(dest_file),
Felipe Leme4bfddbd2017-08-15 18:09:54 -0700188 false, StrEq("pulling da_bugreport.zip")))
Felipe Lemeb3239722016-07-29 17:57:00 -0700189 .WillOnce(Return(true));
190
Felipe Lemef33fcb62016-08-04 12:03:06 -0700191 const char* args[] = {"bugreport"};
Josh Gaob122b172017-08-16 16:57:01 -0700192 ASSERT_EQ(0, br_.DoIt(1, args));
Felipe Lemeb3239722016-07-29 17:57:00 -0700193}
194
195// Tests the 'adb bugreport' option when the device supports 'bugreportz' version 1.1 - it will
196// save the bugreport in the current directory with the name provided by the device.
197TEST_F(BugreportTest, NoArgumentsPostNDevice) {
198 ExpectBugreportzVersion("1.1");
199 std::string dest_file =
200 android::base::StringPrintf("%s%cda_bugreport.zip", cwd_.c_str(), OS_PATH_SEPARATOR);
Felipe Leme4cc03612017-05-02 10:06:33 -0700201 ExpectProgress(50, "da_bugreport.zip");
Josh Gaob122b172017-08-16 16:57:01 -0700202 EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _))
203 .WillOnce(DoAll(WithArg<2>(WriteOnStdout("BEGIN:/device/da_bugreport.zip\n")),
204 WithArg<2>(WriteOnStdout("PROGRESS:50/100\n")),
205 WithArg<2>(WriteOnStdout("OK:/device/da_bugreport.zip\n")),
206 WithArg<2>(ReturnCallbackDone())));
Felipe Lemeb3239722016-07-29 17:57:00 -0700207 EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/da_bugreport.zip")), StrEq(dest_file),
Felipe Leme4bfddbd2017-08-15 18:09:54 -0700208 false, StrEq("pulling da_bugreport.zip")))
Felipe Lemeb3239722016-07-29 17:57:00 -0700209 .WillOnce(Return(true));
210
Felipe Lemef33fcb62016-08-04 12:03:06 -0700211 const char* args[] = {"bugreport"};
Josh Gaob122b172017-08-16 16:57:01 -0700212 ASSERT_EQ(0, br_.DoIt(1, args));
Felipe Lemeb3239722016-07-29 17:57:00 -0700213}
214
215// Tests 'adb bugreport file.zip' when it succeeds and device does not support progress.
216TEST_F(BugreportTest, OkNDevice) {
217 ExpectBugreportzVersion("1.0");
Josh Gaob122b172017-08-16 16:57:01 -0700218 EXPECT_CALL(br_, SendShellCommand("bugreportz", false, _))
219 .WillOnce(DoAll(WithArg<2>(WriteOnStdout("OK:/device/bugreport.zip")),
220 WithArg<2>(ReturnCallbackDone())));
Felipe Leme698e0652016-07-19 17:07:22 -0700221 EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
Felipe Leme4bfddbd2017-08-15 18:09:54 -0700222 false, StrEq("pulling file.zip")))
Felipe Leme698e0652016-07-19 17:07:22 -0700223 .WillOnce(Return(true));
224
Felipe Lemef33fcb62016-08-04 12:03:06 -0700225 const char* args[] = {"bugreport", "file.zip"};
Josh Gaob122b172017-08-16 16:57:01 -0700226 ASSERT_EQ(0, br_.DoIt(2, args));
Felipe Leme698e0652016-07-19 17:07:22 -0700227}
228
Felipe Leme0d4f0502016-07-26 12:14:39 -0700229// Tests 'adb bugreport file.zip' when it succeeds but response was sent in
Felipe Leme6f5080f2016-07-26 12:23:40 -0700230// multiple buffer writers and without progress updates.
Felipe Lemeb3239722016-07-29 17:57:00 -0700231TEST_F(BugreportTest, OkNDeviceSplitBuffer) {
232 ExpectBugreportzVersion("1.0");
Josh Gaob122b172017-08-16 16:57:01 -0700233 EXPECT_CALL(br_, SendShellCommand("bugreportz", false, _))
234 .WillOnce(DoAll(WithArg<2>(WriteOnStdout("OK:/device")),
235 WithArg<2>(WriteOnStdout("/bugreport.zip")),
236 WithArg<2>(ReturnCallbackDone())));
Felipe Leme0d4f0502016-07-26 12:14:39 -0700237 EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
Felipe Leme4bfddbd2017-08-15 18:09:54 -0700238 false, StrEq("pulling file.zip")))
Felipe Leme0d4f0502016-07-26 12:14:39 -0700239 .WillOnce(Return(true));
240
Felipe Lemef33fcb62016-08-04 12:03:06 -0700241 const char* args[] = {"bugreport", "file.zip"};
Josh Gaob122b172017-08-16 16:57:01 -0700242 ASSERT_EQ(0, br_.DoIt(2, args));
Felipe Leme0d4f0502016-07-26 12:14:39 -0700243}
244
Felipe Leme6f5080f2016-07-26 12:23:40 -0700245// Tests 'adb bugreport file.zip' when it succeeds and displays progress.
Felipe Lemeb3239722016-07-29 17:57:00 -0700246TEST_F(BugreportTest, OkProgress) {
247 ExpectBugreportzVersion("1.1");
Felipe Leme4cc03612017-05-02 10:06:33 -0700248 ExpectProgress(1);
249 ExpectProgress(10);
250 ExpectProgress(50);
251 ExpectProgress(99);
Felipe Leme6f5080f2016-07-26 12:23:40 -0700252 // clang-format off
Josh Gaob122b172017-08-16 16:57:01 -0700253 EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _))
Felipe Lemeb3239722016-07-29 17:57:00 -0700254 // NOTE: DoAll accepts at most 10 arguments, and we're almost reached that limit...
Felipe Leme6f5080f2016-07-26 12:23:40 -0700255 .WillOnce(DoAll(
Felipe Lemeb3239722016-07-29 17:57:00 -0700256 // Name might change on OK, so make sure the right one is picked.
Josh Gaob122b172017-08-16 16:57:01 -0700257 WithArg<2>(WriteOnStdout("BEGIN:/device/bugreport___NOT.zip\n")),
Felipe Leme6f5080f2016-07-26 12:23:40 -0700258 // Progress line in one write
Josh Gaob122b172017-08-16 16:57:01 -0700259 WithArg<2>(WriteOnStdout("PROGRESS:1/100\n")),
Felipe Leme6f5080f2016-07-26 12:23:40 -0700260 // Add some bogus lines
Josh Gaob122b172017-08-16 16:57:01 -0700261 WithArg<2>(WriteOnStdout("\nDUDE:SWEET\n\nBLA\n\nBLA\nBLA\n\n")),
Felipe Leme6f5080f2016-07-26 12:23:40 -0700262 // Multiple progress lines in one write
Josh Gaob122b172017-08-16 16:57:01 -0700263 WithArg<2>(WriteOnStdout("PROGRESS:10/100\nPROGRESS:50/100\n")),
Felipe Leme6f5080f2016-07-26 12:23:40 -0700264 // Progress line in multiple writes
Josh Gaob122b172017-08-16 16:57:01 -0700265 WithArg<2>(WriteOnStdout("PROG")),
266 WithArg<2>(WriteOnStdout("RESS:99")),
267 WithArg<2>(WriteOnStdout("/100\n")),
Felipe Leme6f5080f2016-07-26 12:23:40 -0700268 // Split last message as well, just in case
Josh Gaob122b172017-08-16 16:57:01 -0700269 WithArg<2>(WriteOnStdout("OK:/device/bugreport")),
270 WithArg<2>(WriteOnStdout(".zip")),
271 WithArg<2>(ReturnCallbackDone())));
Felipe Leme6e286962016-07-29 15:47:00 -0700272 // clang-format on
Felipe Leme6f5080f2016-07-26 12:23:40 -0700273 EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
Felipe Leme4bfddbd2017-08-15 18:09:54 -0700274 false, StrEq("pulling file.zip")))
Felipe Leme6f5080f2016-07-26 12:23:40 -0700275 .WillOnce(Return(true));
276
Felipe Lemef33fcb62016-08-04 12:03:06 -0700277 const char* args[] = {"bugreport", "file.zip"};
Josh Gaob122b172017-08-16 16:57:01 -0700278 ASSERT_EQ(0, br_.DoIt(2, args));
Felipe Leme6f5080f2016-07-26 12:23:40 -0700279}
280
Felipe Lemededcbaa2017-03-20 11:00:11 -0700281// Tests 'adb bugreport file.zip' when it succeeds and displays progress, even if progress recedes.
282TEST_F(BugreportTest, OkProgressAlwaysForward) {
283 ExpectBugreportzVersion("1.1");
Felipe Leme4cc03612017-05-02 10:06:33 -0700284 ExpectProgress(1);
285 ExpectProgress(50);
286 ExpectProgress(75);
Felipe Lemededcbaa2017-03-20 11:00:11 -0700287 // clang-format off
Josh Gaob122b172017-08-16 16:57:01 -0700288 EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _))
Felipe Lemededcbaa2017-03-20 11:00:11 -0700289 // NOTE: DoAll accepts at most 10 arguments, and we're almost reached that limit...
290 .WillOnce(DoAll(
Josh Gaob122b172017-08-16 16:57:01 -0700291 WithArg<2>(WriteOnStdout("BEGIN:/device/bugreport.zip\n")),
292 WithArg<2>(WriteOnStdout("PROGRESS:1/100\n")), // 1%
293 WithArg<2>(WriteOnStdout("PROGRESS:50/100\n")), // 50%
Felipe Leme4cc03612017-05-02 10:06:33 -0700294 // 25% should be ignored becaused it receded.
Josh Gaob122b172017-08-16 16:57:01 -0700295 WithArg<2>(WriteOnStdout("PROGRESS:25/100\n")), // 25%
296 WithArg<2>(WriteOnStdout("PROGRESS:75/100\n")), // 75%
Felipe Leme4cc03612017-05-02 10:06:33 -0700297 // 75% should be ignored becaused it didn't change.
Josh Gaob122b172017-08-16 16:57:01 -0700298 WithArg<2>(WriteOnStdout("PROGRESS:75/100\n")), // 75%
Felipe Leme4cc03612017-05-02 10:06:33 -0700299 // Try a receeding percentage with a different max progress
Josh Gaob122b172017-08-16 16:57:01 -0700300 WithArg<2>(WriteOnStdout("PROGRESS:700/1000\n")), // 70%
301 WithArg<2>(WriteOnStdout("OK:/device/bugreport.zip")),
302 WithArg<2>(ReturnCallbackDone())));
Felipe Lemededcbaa2017-03-20 11:00:11 -0700303 // clang-format on
304 EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
Felipe Leme4bfddbd2017-08-15 18:09:54 -0700305 false, StrEq("pulling file.zip")))
Felipe Lemededcbaa2017-03-20 11:00:11 -0700306 .WillOnce(Return(true));
307
308 const char* args[] = {"bugreport", "file.zip"};
Josh Gaob122b172017-08-16 16:57:01 -0700309 ASSERT_EQ(0, br_.DoIt(2, args));
Felipe Lemededcbaa2017-03-20 11:00:11 -0700310}
311
Felipe Lemee5d665b2017-05-23 16:56:47 -0700312// Tests 'adb bugreport file.zip' when it succeeds and displays the initial progress of 0%
313TEST_F(BugreportTest, OkProgressZeroPercentIsNotIgnored) {
314 ExpectBugreportzVersion("1.1");
315 ExpectProgress(0);
316 ExpectProgress(1);
317 // clang-format off
Josh Gaob122b172017-08-16 16:57:01 -0700318 EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _))
Felipe Lemee5d665b2017-05-23 16:56:47 -0700319 // NOTE: DoAll accepts at most 10 arguments, and we're almost reached that limit...
320 .WillOnce(DoAll(
Josh Gaob122b172017-08-16 16:57:01 -0700321 WithArg<2>(WriteOnStdout("BEGIN:/device/bugreport.zip\n")),
322 WithArg<2>(WriteOnStdout("PROGRESS:1/100000\n")),
323 WithArg<2>(WriteOnStdout("PROGRESS:1/100\n")), // 1%
324 WithArg<2>(WriteOnStdout("OK:/device/bugreport.zip")),
325 WithArg<2>(ReturnCallbackDone())));
Felipe Lemee5d665b2017-05-23 16:56:47 -0700326 // clang-format on
327 EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
Felipe Leme4bfddbd2017-08-15 18:09:54 -0700328 false, StrEq("pulling file.zip")))
Felipe Lemee5d665b2017-05-23 16:56:47 -0700329 .WillOnce(Return(true));
330
331 const char* args[] = {"bugreport", "file.zip"};
Josh Gaob122b172017-08-16 16:57:01 -0700332 ASSERT_EQ(0, br_.DoIt(2, args));
Felipe Lemee5d665b2017-05-23 16:56:47 -0700333}
334
Felipe Lemeb3239722016-07-29 17:57:00 -0700335// Tests 'adb bugreport dir' when it succeeds and destination is a directory.
336TEST_F(BugreportTest, OkDirectory) {
337 ExpectBugreportzVersion("1.1");
338 TemporaryDir td;
339 std::string dest_file =
340 android::base::StringPrintf("%s%cda_bugreport.zip", td.path, OS_PATH_SEPARATOR);
341
Josh Gaob122b172017-08-16 16:57:01 -0700342 EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _))
343 .WillOnce(DoAll(WithArg<2>(WriteOnStdout("BEGIN:/device/da_bugreport.zip\n")),
344 WithArg<2>(WriteOnStdout("OK:/device/da_bugreport.zip")),
345 WithArg<2>(ReturnCallbackDone())));
Felipe Lemeb3239722016-07-29 17:57:00 -0700346 EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/da_bugreport.zip")), StrEq(dest_file),
Felipe Leme4bfddbd2017-08-15 18:09:54 -0700347 false, StrEq("pulling da_bugreport.zip")))
Felipe Lemeb3239722016-07-29 17:57:00 -0700348 .WillOnce(Return(true));
349
Felipe Lemef33fcb62016-08-04 12:03:06 -0700350 const char* args[] = {"bugreport", td.path};
Josh Gaob122b172017-08-16 16:57:01 -0700351 ASSERT_EQ(0, br_.DoIt(2, args));
Felipe Lemeb3239722016-07-29 17:57:00 -0700352}
353
Felipe Leme6f5080f2016-07-26 12:23:40 -0700354// Tests 'adb bugreport file' when it succeeds
355TEST_F(BugreportTest, OkNoExtension) {
Felipe Lemeb3239722016-07-29 17:57:00 -0700356 ExpectBugreportzVersion("1.1");
Josh Gaob122b172017-08-16 16:57:01 -0700357 EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _))
358 .WillOnce(DoAll(WithArg<2>(WriteOnStdout("OK:/device/bugreport.zip\n")),
359 WithArg<2>(ReturnCallbackDone())));
Felipe Leme6f5080f2016-07-26 12:23:40 -0700360 EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
Felipe Leme4bfddbd2017-08-15 18:09:54 -0700361 false, StrEq("pulling file.zip")))
Felipe Leme6f5080f2016-07-26 12:23:40 -0700362 .WillOnce(Return(true));
363
Felipe Lemef33fcb62016-08-04 12:03:06 -0700364 const char* args[] = {"bugreport", "file"};
Josh Gaob122b172017-08-16 16:57:01 -0700365 ASSERT_EQ(0, br_.DoIt(2, args));
Felipe Leme6f5080f2016-07-26 12:23:40 -0700366}
367
Felipe Lemeb3239722016-07-29 17:57:00 -0700368// Tests 'adb bugreport dir' when it succeeds and destination is a directory and device runs N.
369TEST_F(BugreportTest, OkNDeviceDirectory) {
370 ExpectBugreportzVersion("1.0");
371 TemporaryDir td;
372 std::string dest_file =
373 android::base::StringPrintf("%s%cda_bugreport.zip", td.path, OS_PATH_SEPARATOR);
374
Josh Gaob122b172017-08-16 16:57:01 -0700375 EXPECT_CALL(br_, SendShellCommand("bugreportz", false, _))
376 .WillOnce(DoAll(WithArg<2>(WriteOnStdout("BEGIN:/device/da_bugreport.zip\n")),
377 WithArg<2>(WriteOnStdout("OK:/device/da_bugreport.zip")),
378 WithArg<2>(ReturnCallbackDone())));
Felipe Lemeb3239722016-07-29 17:57:00 -0700379 EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/da_bugreport.zip")), StrEq(dest_file),
Felipe Leme4bfddbd2017-08-15 18:09:54 -0700380 false, StrEq("pulling da_bugreport.zip")))
Felipe Lemeb3239722016-07-29 17:57:00 -0700381 .WillOnce(Return(true));
382
Felipe Lemef33fcb62016-08-04 12:03:06 -0700383 const char* args[] = {"bugreport", td.path};
Josh Gaob122b172017-08-16 16:57:01 -0700384 ASSERT_EQ(0, br_.DoIt(2, args));
Felipe Lemeb3239722016-07-29 17:57:00 -0700385}
386
Felipe Leme698e0652016-07-19 17:07:22 -0700387// Tests 'adb bugreport file.zip' when the bugreport itself failed
388TEST_F(BugreportTest, BugreportzReturnedFail) {
Felipe Lemeb3239722016-07-29 17:57:00 -0700389 ExpectBugreportzVersion("1.1");
Josh Gaob122b172017-08-16 16:57:01 -0700390 EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _))
Felipe Leme6f5080f2016-07-26 12:23:40 -0700391 .WillOnce(
Josh Gaob122b172017-08-16 16:57:01 -0700392 DoAll(WithArg<2>(WriteOnStdout("FAIL:D'OH!\n")), WithArg<2>(ReturnCallbackDone())));
Felipe Leme0d4f0502016-07-26 12:14:39 -0700393
394 CaptureStderr();
Felipe Lemef33fcb62016-08-04 12:03:06 -0700395 const char* args[] = {"bugreport", "file.zip"};
Josh Gaob122b172017-08-16 16:57:01 -0700396 ASSERT_EQ(-1, br_.DoIt(2, args));
Felipe Leme6f5080f2016-07-26 12:23:40 -0700397 ASSERT_THAT(GetCapturedStderr(), HasSubstr("D'OH!"));
Felipe Leme0d4f0502016-07-26 12:14:39 -0700398}
399
400// Tests 'adb bugreport file.zip' when the bugreport itself failed but response
401// was sent in
402// multiple buffer writes
403TEST_F(BugreportTest, BugreportzReturnedFailSplitBuffer) {
Felipe Lemeb3239722016-07-29 17:57:00 -0700404 ExpectBugreportzVersion("1.1");
Josh Gaob122b172017-08-16 16:57:01 -0700405 EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _))
406 .WillOnce(DoAll(WithArg<2>(WriteOnStdout("FAIL")), WithArg<2>(WriteOnStdout(":D'OH!\n")),
407 WithArg<2>(ReturnCallbackDone())));
Felipe Leme698e0652016-07-19 17:07:22 -0700408
409 CaptureStderr();
Felipe Lemef33fcb62016-08-04 12:03:06 -0700410 const char* args[] = {"bugreport", "file.zip"};
Josh Gaob122b172017-08-16 16:57:01 -0700411 ASSERT_EQ(-1, br_.DoIt(2, args));
Felipe Leme6f5080f2016-07-26 12:23:40 -0700412 ASSERT_THAT(GetCapturedStderr(), HasSubstr("D'OH!"));
Felipe Leme698e0652016-07-19 17:07:22 -0700413}
414
415// Tests 'adb bugreport file.zip' when the bugreportz returned an unsupported
416// response.
417TEST_F(BugreportTest, BugreportzReturnedUnsupported) {
Felipe Lemeb3239722016-07-29 17:57:00 -0700418 ExpectBugreportzVersion("1.1");
Josh Gaob122b172017-08-16 16:57:01 -0700419 EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _))
420 .WillOnce(DoAll(WithArg<2>(WriteOnStdout("bugreportz? What am I, a zombie?")),
421 WithArg<2>(ReturnCallbackDone())));
Felipe Leme698e0652016-07-19 17:07:22 -0700422
423 CaptureStderr();
Felipe Lemef33fcb62016-08-04 12:03:06 -0700424 const char* args[] = {"bugreport", "file.zip"};
Josh Gaob122b172017-08-16 16:57:01 -0700425 ASSERT_EQ(-1, br_.DoIt(2, args));
Felipe Leme698e0652016-07-19 17:07:22 -0700426 ASSERT_THAT(GetCapturedStderr(), HasSubstr("bugreportz? What am I, a zombie?"));
427}
428
Felipe Leme6f5080f2016-07-26 12:23:40 -0700429// Tests 'adb bugreport file.zip' when the bugreportz -v command failed
430TEST_F(BugreportTest, BugreportzVersionFailed) {
Josh Gaob122b172017-08-16 16:57:01 -0700431 EXPECT_CALL(br_, SendShellCommand("bugreportz -v", false, _)).WillOnce(Return(666));
Felipe Leme6f5080f2016-07-26 12:23:40 -0700432
Felipe Lemef33fcb62016-08-04 12:03:06 -0700433 const char* args[] = {"bugreport", "file.zip"};
Josh Gaob122b172017-08-16 16:57:01 -0700434 ASSERT_EQ(666, br_.DoIt(2, args));
Felipe Leme6f5080f2016-07-26 12:23:40 -0700435}
436
Felipe Leme6e286962016-07-29 15:47:00 -0700437// Tests 'adb bugreport file.zip' when the bugreportz -v returns status 0 but with no output.
438TEST_F(BugreportTest, BugreportzVersionEmpty) {
Felipe Lemeb3239722016-07-29 17:57:00 -0700439 ExpectBugreportzVersion("");
Felipe Leme6e286962016-07-29 15:47:00 -0700440
Felipe Lemef33fcb62016-08-04 12:03:06 -0700441 const char* args[] = {"bugreport", "file.zip"};
Josh Gaob122b172017-08-16 16:57:01 -0700442 ASSERT_EQ(-1, br_.DoIt(2, args));
Felipe Leme6e286962016-07-29 15:47:00 -0700443}
444
Felipe Leme6f5080f2016-07-26 12:23:40 -0700445// Tests 'adb bugreport file.zip' when the main bugreportz command failed
Felipe Leme698e0652016-07-19 17:07:22 -0700446TEST_F(BugreportTest, BugreportzFailed) {
Felipe Lemeb3239722016-07-29 17:57:00 -0700447 ExpectBugreportzVersion("1.1");
Josh Gaob122b172017-08-16 16:57:01 -0700448 EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _)).WillOnce(Return(666));
Felipe Leme698e0652016-07-19 17:07:22 -0700449
Felipe Lemef33fcb62016-08-04 12:03:06 -0700450 const char* args[] = {"bugreport", "file.zip"};
Josh Gaob122b172017-08-16 16:57:01 -0700451 ASSERT_EQ(666, br_.DoIt(2, args));
Felipe Leme698e0652016-07-19 17:07:22 -0700452}
453
454// Tests 'adb bugreport file.zip' when the bugreport could not be pulled
455TEST_F(BugreportTest, PullFails) {
Felipe Lemeb3239722016-07-29 17:57:00 -0700456 ExpectBugreportzVersion("1.1");
Josh Gaob122b172017-08-16 16:57:01 -0700457 EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _))
458 .WillOnce(DoAll(WithArg<2>(WriteOnStdout("OK:/device/bugreport.zip")),
459 WithArg<2>(ReturnCallbackDone())));
Felipe Leme698e0652016-07-19 17:07:22 -0700460 EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
Felipe Leme4bfddbd2017-08-15 18:09:54 -0700461 false, HasSubstr("file.zip")))
Felipe Leme698e0652016-07-19 17:07:22 -0700462 .WillOnce(Return(false));
463
Felipe Lemef33fcb62016-08-04 12:03:06 -0700464 const char* args[] = {"bugreport", "file.zip"};
Josh Gaob122b172017-08-16 16:57:01 -0700465 ASSERT_EQ(1, br_.DoIt(2, args));
Felipe Leme698e0652016-07-19 17:07:22 -0700466}