1 /*
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
22 #include <android-base/strings.h>
23 #include <android-base/test_utils.h>
24
25 #include "sysdeps.h"
26 #include "adb_utils.h"
27
28 using ::testing::_;
29 using ::testing::Action;
30 using ::testing::ActionInterface;
31 using ::testing::DoAll;
32 using ::testing::ElementsAre;
33 using ::testing::HasSubstr;
34 using ::testing::MakeAction;
35 using ::testing::Return;
36 using ::testing::StrEq;
37 using ::testing::WithArg;
38 using ::testing::internal::CaptureStderr;
39 using ::testing::internal::CaptureStdout;
40 using ::testing::internal::GetCapturedStderr;
41 using ::testing::internal::GetCapturedStdout;
42
43 // Empty function so tests don't need to be linked against file_sync_service.cpp, which requires
44 // SELinux and its transitive dependencies...
do_sync_pull(const std::vector<const char * > & srcs,const char * dst,bool copy_attrs,const char * name)45 bool 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
51 // Empty functions so tests don't need to be linked against commandline.cpp
52 DefaultStandardStreamsCallback DEFAULT_STANDARD_STREAMS_CALLBACK(nullptr, nullptr);
53
send_shell_command(TransportType transport_type,const char * serial,const std::string & command,bool disable_shell_protocol,StandardStreamsCallbackInterface * callback)54 int send_shell_command(TransportType transport_type, const char* serial, const std::string& command,
55 bool disable_shell_protocol, StandardStreamsCallbackInterface* callback) {
56 ADD_FAILURE() << "send_shell_command() should have been mocked";
57 return -42;
58 }
59
60 enum StreamType {
61 kStreamStdout,
62 kStreamStderr,
63 };
64
65 // gmock black magic to provide a WithArg<4>(WriteOnStdout(output)) matcher
66 typedef void OnStandardStreamsCallbackFunction(StandardStreamsCallbackInterface*);
67
68 class OnStandardStreamsCallbackAction : public ActionInterface<OnStandardStreamsCallbackFunction> {
69 public:
OnStandardStreamsCallbackAction(StreamType type,const std::string & output)70 explicit OnStandardStreamsCallbackAction(StreamType type, const std::string& output)
71 : type_(type), output_(output) {
72 }
Perform(const ArgumentTuple & args)73 virtual Result Perform(const ArgumentTuple& args) {
74 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 }
80 }
81
82 private:
83 StreamType type_;
84 std::string output_;
85 };
86
87 // Matcher used to emulated StandardStreamsCallbackInterface.OnStdout(buffer,
88 // length)
WriteOnStdout(const std::string & output)89 Action<OnStandardStreamsCallbackFunction> WriteOnStdout(const std::string& output) {
90 return MakeAction(new OnStandardStreamsCallbackAction(kStreamStdout, output));
91 }
92
93 // Matcher used to emulated StandardStreamsCallbackInterface.OnStderr(buffer,
94 // length)
WriteOnStderr(const std::string & output)95 Action<OnStandardStreamsCallbackFunction> WriteOnStderr(const std::string& output) {
96 return MakeAction(new OnStandardStreamsCallbackAction(kStreamStderr, output));
97 }
98
99 typedef int CallbackDoneFunction(StandardStreamsCallbackInterface*);
100
101 class CallbackDoneAction : public ActionInterface<CallbackDoneFunction> {
102 public:
CallbackDoneAction(int status)103 explicit CallbackDoneAction(int status) : status_(status) {
104 }
Perform(const ArgumentTuple & args)105 virtual Result Perform(const ArgumentTuple& args) {
106 int status = ::std::tr1::get<0>(args)->Done(status_);
107 return status;
108 }
109
110 private:
111 int status_;
112 };
113
114 // Matcher used to emulated StandardStreamsCallbackInterface.Done(status)
ReturnCallbackDone(int status=-1337)115 Action<CallbackDoneFunction> ReturnCallbackDone(int status = -1337) {
116 return MakeAction(new CallbackDoneAction(status));
117 }
118
119 class BugreportMock : public Bugreport {
120 public:
121 MOCK_METHOD5(SendShellCommand,
122 int(TransportType transport_type, const char* serial, const std::string& command,
123 bool disable_shell_protocol, StandardStreamsCallbackInterface* callback));
124 MOCK_METHOD4(DoSyncPull, bool(const std::vector<const char*>& srcs, const char* dst,
125 bool copy_attrs, const char* name));
126 MOCK_METHOD2(UpdateProgress, void(const std::string&, int));
127 };
128
129 class BugreportTest : public ::testing::Test {
130 public:
SetUp()131 void SetUp() {
132 if (!getcwd(&cwd_)) {
133 ADD_FAILURE() << "getcwd failed: " << strerror(errno);
134 return;
135 }
136 }
137
ExpectBugreportzVersion(const std::string & version)138 void ExpectBugreportzVersion(const std::string& version) {
139 EXPECT_CALL(br_,
140 SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -v", false, _))
141 .WillOnce(DoAll(WithArg<4>(WriteOnStderr(version.c_str())),
142 WithArg<4>(ReturnCallbackDone(0))));
143 }
144
ExpectProgress(int progress_percentage,const std::string & file="file.zip")145 void ExpectProgress(int progress_percentage, const std::string& file = "file.zip") {
146 EXPECT_CALL(br_, UpdateProgress(StrEq("generating " + file), progress_percentage));
147 }
148
149 BugreportMock br_;
150 std::string cwd_; // TODO: make it static
151 };
152
153 // Tests when called with invalid number of arguments
TEST_F(BugreportTest,InvalidNumberArgs)154 TEST_F(BugreportTest, InvalidNumberArgs) {
155 const char* args[] = {"bugreport", "to", "principal"};
156 ASSERT_EQ(1, br_.DoIt(kTransportLocal, "HannibalLecter", 3, args));
157 }
158
159 // Tests the 'adb bugreport' option when the device does not support 'bugreportz' - it falls back
160 // to the flat-file format ('bugreport' binary on device)
TEST_F(BugreportTest,NoArgumentsPreNDevice)161 TEST_F(BugreportTest, NoArgumentsPreNDevice) {
162 // clang-format off
163 EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -v", false, _))
164 .WillOnce(DoAll(WithArg<4>(WriteOnStderr("")),
165 // Write some bogus output on stdout to make sure it's ignored
166 WithArg<4>(WriteOnStdout("Dude, where is my bugreportz?")),
167 WithArg<4>(ReturnCallbackDone(0))));
168 // clang-format on
169 std::string bugreport = "Reported the bug was.";
170 CaptureStdout();
171 EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreport", false, _))
172 .WillOnce(DoAll(WithArg<4>(WriteOnStdout(bugreport)), Return(0)));
173
174 const char* args[] = {"bugreport"};
175 ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 1, args));
176 ASSERT_THAT(GetCapturedStdout(), StrEq(bugreport));
177 }
178
179 // Tests the 'adb bugreport' option when the device supports 'bugreportz' version 1.0 - it will
180 // save the bugreport in the current directory with the name provided by the device.
TEST_F(BugreportTest,NoArgumentsNDevice)181 TEST_F(BugreportTest, NoArgumentsNDevice) {
182 ExpectBugreportzVersion("1.0");
183
184 std::string dest_file =
185 android::base::StringPrintf("%s%cda_bugreport.zip", cwd_.c_str(), OS_PATH_SEPARATOR);
186 EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz", false, _))
187 .WillOnce(DoAll(WithArg<4>(WriteOnStdout("OK:/device/da_bugreport.zip")),
188 WithArg<4>(ReturnCallbackDone())));
189 EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/da_bugreport.zip")), StrEq(dest_file),
190 true, StrEq("pulling da_bugreport.zip")))
191 .WillOnce(Return(true));
192
193 const char* args[] = {"bugreport"};
194 ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 1, args));
195 }
196
197 // Tests the 'adb bugreport' option when the device supports 'bugreportz' version 1.1 - it will
198 // save the bugreport in the current directory with the name provided by the device.
TEST_F(BugreportTest,NoArgumentsPostNDevice)199 TEST_F(BugreportTest, NoArgumentsPostNDevice) {
200 ExpectBugreportzVersion("1.1");
201 std::string dest_file =
202 android::base::StringPrintf("%s%cda_bugreport.zip", cwd_.c_str(), OS_PATH_SEPARATOR);
203 ExpectProgress(50, "da_bugreport.zip");
204 EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
205 .WillOnce(DoAll(WithArg<4>(WriteOnStdout("BEGIN:/device/da_bugreport.zip\n")),
206 WithArg<4>(WriteOnStdout("PROGRESS:50/100\n")),
207 WithArg<4>(WriteOnStdout("OK:/device/da_bugreport.zip\n")),
208 WithArg<4>(ReturnCallbackDone())));
209 EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/da_bugreport.zip")), StrEq(dest_file),
210 true, StrEq("pulling da_bugreport.zip")))
211 .WillOnce(Return(true));
212
213 const char* args[] = {"bugreport"};
214 ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 1, args));
215 }
216
217 // Tests 'adb bugreport file.zip' when it succeeds and device does not support progress.
TEST_F(BugreportTest,OkNDevice)218 TEST_F(BugreportTest, OkNDevice) {
219 ExpectBugreportzVersion("1.0");
220 EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz", false, _))
221 .WillOnce(DoAll(WithArg<4>(WriteOnStdout("OK:/device/bugreport.zip")),
222 WithArg<4>(ReturnCallbackDone())));
223 EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
224 true, StrEq("pulling file.zip")))
225 .WillOnce(Return(true));
226
227 const char* args[] = {"bugreport", "file.zip"};
228 ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
229 }
230
231 // Tests 'adb bugreport file.zip' when it succeeds but response was sent in
232 // multiple buffer writers and without progress updates.
TEST_F(BugreportTest,OkNDeviceSplitBuffer)233 TEST_F(BugreportTest, OkNDeviceSplitBuffer) {
234 ExpectBugreportzVersion("1.0");
235 EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz", false, _))
236 .WillOnce(DoAll(WithArg<4>(WriteOnStdout("OK:/device")),
237 WithArg<4>(WriteOnStdout("/bugreport.zip")),
238 WithArg<4>(ReturnCallbackDone())));
239 EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
240 true, StrEq("pulling file.zip")))
241 .WillOnce(Return(true));
242
243 const char* args[] = {"bugreport", "file.zip"};
244 ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
245 }
246
247 // Tests 'adb bugreport file.zip' when it succeeds and displays progress.
TEST_F(BugreportTest,OkProgress)248 TEST_F(BugreportTest, OkProgress) {
249 ExpectBugreportzVersion("1.1");
250 ExpectProgress(1);
251 ExpectProgress(10);
252 ExpectProgress(50);
253 ExpectProgress(99);
254 // clang-format off
255 EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
256 // NOTE: DoAll accepts at most 10 arguments, and we're almost reached that limit...
257 .WillOnce(DoAll(
258 // Name might change on OK, so make sure the right one is picked.
259 WithArg<4>(WriteOnStdout("BEGIN:/device/bugreport___NOT.zip\n")),
260 // Progress line in one write
261 WithArg<4>(WriteOnStdout("PROGRESS:1/100\n")),
262 // Add some bogus lines
263 WithArg<4>(WriteOnStdout("\nDUDE:SWEET\n\nBLA\n\nBLA\nBLA\n\n")),
264 // Multiple progress lines in one write
265 WithArg<4>(WriteOnStdout("PROGRESS:10/100\nPROGRESS:50/100\n")),
266 // Progress line in multiple writes
267 WithArg<4>(WriteOnStdout("PROG")),
268 WithArg<4>(WriteOnStdout("RESS:99")),
269 WithArg<4>(WriteOnStdout("/100\n")),
270 // Split last message as well, just in case
271 WithArg<4>(WriteOnStdout("OK:/device/bugreport")),
272 WithArg<4>(WriteOnStdout(".zip")),
273 WithArg<4>(ReturnCallbackDone())));
274 // clang-format on
275 EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
276 true, StrEq("pulling file.zip")))
277 .WillOnce(Return(true));
278
279 const char* args[] = {"bugreport", "file.zip"};
280 ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
281 }
282
283 // Tests 'adb bugreport file.zip' when it succeeds and displays progress, even if progress recedes.
TEST_F(BugreportTest,OkProgressAlwaysForward)284 TEST_F(BugreportTest, OkProgressAlwaysForward) {
285 ExpectBugreportzVersion("1.1");
286 ExpectProgress(1);
287 ExpectProgress(50);
288 ExpectProgress(75);
289 // clang-format off
290 EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
291 // NOTE: DoAll accepts at most 10 arguments, and we're almost reached that limit...
292 .WillOnce(DoAll(
293 WithArg<4>(WriteOnStdout("BEGIN:/device/bugreport.zip\n")),
294 WithArg<4>(WriteOnStdout("PROGRESS:1/100\n")), // 1%
295 WithArg<4>(WriteOnStdout("PROGRESS:50/100\n")), // 50%
296 // 25% should be ignored becaused it receded.
297 WithArg<4>(WriteOnStdout("PROGRESS:25/100\n")), // 25%
298 WithArg<4>(WriteOnStdout("PROGRESS:75/100\n")), // 75%
299 // 75% should be ignored becaused it didn't change.
300 WithArg<4>(WriteOnStdout("PROGRESS:75/100\n")), // 75%
301 // Try a receeding percentage with a different max progress
302 WithArg<4>(WriteOnStdout("PROGRESS:700/1000\n")), // 70%
303 WithArg<4>(WriteOnStdout("OK:/device/bugreport.zip")),
304 WithArg<4>(ReturnCallbackDone())));
305 // clang-format on
306 EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
307 true, StrEq("pulling file.zip")))
308 .WillOnce(Return(true));
309
310 const char* args[] = {"bugreport", "file.zip"};
311 ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
312 }
313
314 // Tests 'adb bugreport file.zip' when it succeeds and displays the initial progress of 0%
TEST_F(BugreportTest,OkProgressZeroPercentIsNotIgnored)315 TEST_F(BugreportTest, OkProgressZeroPercentIsNotIgnored) {
316 ExpectBugreportzVersion("1.1");
317 ExpectProgress(0);
318 ExpectProgress(1);
319 // clang-format off
320 EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
321 // NOTE: DoAll accepts at most 10 arguments, and we're almost reached that limit...
322 .WillOnce(DoAll(
323 WithArg<4>(WriteOnStdout("BEGIN:/device/bugreport.zip\n")),
324 WithArg<4>(WriteOnStdout("PROGRESS:1/100000\n")),
325 WithArg<4>(WriteOnStdout("PROGRESS:1/100\n")), // 1%
326 WithArg<4>(WriteOnStdout("OK:/device/bugreport.zip")),
327 WithArg<4>(ReturnCallbackDone())));
328 // clang-format on
329 EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
330 true, StrEq("pulling file.zip")))
331 .WillOnce(Return(true));
332
333 const char* args[] = {"bugreport", "file.zip"};
334 ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
335 }
336
337 // Tests 'adb bugreport dir' when it succeeds and destination is a directory.
TEST_F(BugreportTest,OkDirectory)338 TEST_F(BugreportTest, OkDirectory) {
339 ExpectBugreportzVersion("1.1");
340 TemporaryDir td;
341 std::string dest_file =
342 android::base::StringPrintf("%s%cda_bugreport.zip", td.path, OS_PATH_SEPARATOR);
343
344 EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
345 .WillOnce(DoAll(WithArg<4>(WriteOnStdout("BEGIN:/device/da_bugreport.zip\n")),
346 WithArg<4>(WriteOnStdout("OK:/device/da_bugreport.zip")),
347 WithArg<4>(ReturnCallbackDone())));
348 EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/da_bugreport.zip")), StrEq(dest_file),
349 true, StrEq("pulling da_bugreport.zip")))
350 .WillOnce(Return(true));
351
352 const char* args[] = {"bugreport", td.path};
353 ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
354 }
355
356 // Tests 'adb bugreport file' when it succeeds
TEST_F(BugreportTest,OkNoExtension)357 TEST_F(BugreportTest, OkNoExtension) {
358 ExpectBugreportzVersion("1.1");
359 EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
360 .WillOnce(DoAll(WithArg<4>(WriteOnStdout("OK:/device/bugreport.zip\n")),
361 WithArg<4>(ReturnCallbackDone())));
362 EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
363 true, StrEq("pulling file.zip")))
364 .WillOnce(Return(true));
365
366 const char* args[] = {"bugreport", "file"};
367 ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
368 }
369
370 // Tests 'adb bugreport dir' when it succeeds and destination is a directory and device runs N.
TEST_F(BugreportTest,OkNDeviceDirectory)371 TEST_F(BugreportTest, OkNDeviceDirectory) {
372 ExpectBugreportzVersion("1.0");
373 TemporaryDir td;
374 std::string dest_file =
375 android::base::StringPrintf("%s%cda_bugreport.zip", td.path, OS_PATH_SEPARATOR);
376
377 EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz", false, _))
378 .WillOnce(DoAll(WithArg<4>(WriteOnStdout("BEGIN:/device/da_bugreport.zip\n")),
379 WithArg<4>(WriteOnStdout("OK:/device/da_bugreport.zip")),
380 WithArg<4>(ReturnCallbackDone())));
381 EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/da_bugreport.zip")), StrEq(dest_file),
382 true, StrEq("pulling da_bugreport.zip")))
383 .WillOnce(Return(true));
384
385 const char* args[] = {"bugreport", td.path};
386 ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
387 }
388
389 // Tests 'adb bugreport file.zip' when the bugreport itself failed
TEST_F(BugreportTest,BugreportzReturnedFail)390 TEST_F(BugreportTest, BugreportzReturnedFail) {
391 ExpectBugreportzVersion("1.1");
392 EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
393 .WillOnce(
394 DoAll(WithArg<4>(WriteOnStdout("FAIL:D'OH!\n")), WithArg<4>(ReturnCallbackDone())));
395
396 CaptureStderr();
397 const char* args[] = {"bugreport", "file.zip"};
398 ASSERT_EQ(-1, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
399 ASSERT_THAT(GetCapturedStderr(), HasSubstr("D'OH!"));
400 }
401
402 // Tests 'adb bugreport file.zip' when the bugreport itself failed but response
403 // was sent in
404 // multiple buffer writes
TEST_F(BugreportTest,BugreportzReturnedFailSplitBuffer)405 TEST_F(BugreportTest, BugreportzReturnedFailSplitBuffer) {
406 ExpectBugreportzVersion("1.1");
407 EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
408 .WillOnce(DoAll(WithArg<4>(WriteOnStdout("FAIL")), WithArg<4>(WriteOnStdout(":D'OH!\n")),
409 WithArg<4>(ReturnCallbackDone())));
410
411 CaptureStderr();
412 const char* args[] = {"bugreport", "file.zip"};
413 ASSERT_EQ(-1, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
414 ASSERT_THAT(GetCapturedStderr(), HasSubstr("D'OH!"));
415 }
416
417 // Tests 'adb bugreport file.zip' when the bugreportz returned an unsupported
418 // response.
TEST_F(BugreportTest,BugreportzReturnedUnsupported)419 TEST_F(BugreportTest, BugreportzReturnedUnsupported) {
420 ExpectBugreportzVersion("1.1");
421 EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
422 .WillOnce(DoAll(WithArg<4>(WriteOnStdout("bugreportz? What am I, a zombie?")),
423 WithArg<4>(ReturnCallbackDone())));
424
425 CaptureStderr();
426 const char* args[] = {"bugreport", "file.zip"};
427 ASSERT_EQ(-1, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
428 ASSERT_THAT(GetCapturedStderr(), HasSubstr("bugreportz? What am I, a zombie?"));
429 }
430
431 // Tests 'adb bugreport file.zip' when the bugreportz -v command failed
TEST_F(BugreportTest,BugreportzVersionFailed)432 TEST_F(BugreportTest, BugreportzVersionFailed) {
433 EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -v", false, _))
434 .WillOnce(Return(666));
435
436 const char* args[] = {"bugreport", "file.zip"};
437 ASSERT_EQ(666, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
438 }
439
440 // Tests 'adb bugreport file.zip' when the bugreportz -v returns status 0 but with no output.
TEST_F(BugreportTest,BugreportzVersionEmpty)441 TEST_F(BugreportTest, BugreportzVersionEmpty) {
442 ExpectBugreportzVersion("");
443
444 const char* args[] = {"bugreport", "file.zip"};
445 ASSERT_EQ(-1, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
446 }
447
448 // Tests 'adb bugreport file.zip' when the main bugreportz command failed
TEST_F(BugreportTest,BugreportzFailed)449 TEST_F(BugreportTest, BugreportzFailed) {
450 ExpectBugreportzVersion("1.1");
451 EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
452 .WillOnce(Return(666));
453
454 const char* args[] = {"bugreport", "file.zip"};
455 ASSERT_EQ(666, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
456 }
457
458 // Tests 'adb bugreport file.zip' when the bugreport could not be pulled
TEST_F(BugreportTest,PullFails)459 TEST_F(BugreportTest, PullFails) {
460 ExpectBugreportzVersion("1.1");
461 EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
462 .WillOnce(DoAll(WithArg<4>(WriteOnStdout("OK:/device/bugreport.zip")),
463 WithArg<4>(ReturnCallbackDone())));
464 EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
465 true, HasSubstr("file.zip")))
466 .WillOnce(Return(false));
467
468 const char* args[] = {"bugreport", "file.zip"};
469 ASSERT_EQ(1, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
470 }
471