blob: 15c6f83f2c7a8db9705027f7219942d83eaf9cde [file] [log] [blame]
Felipe Leme042c3512016-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
22using ::testing::_;
Felipe Leme60192aa2016-07-26 12:14:39 -070023using ::testing::Action;
24using ::testing::ActionInterface;
Felipe Leme042c3512016-07-19 17:07:22 -070025using ::testing::DoAll;
26using ::testing::ElementsAre;
27using ::testing::HasSubstr;
Felipe Leme60192aa2016-07-26 12:14:39 -070028using ::testing::MakeAction;
Felipe Leme042c3512016-07-19 17:07:22 -070029using ::testing::Return;
Felipe Leme042c3512016-07-19 17:07:22 -070030using ::testing::StrEq;
Felipe Leme60192aa2016-07-26 12:14:39 -070031using ::testing::WithArg;
Felipe Leme042c3512016-07-19 17:07:22 -070032using ::testing::internal::CaptureStderr;
33using ::testing::internal::GetCapturedStderr;
34
Felipe Leme60192aa2016-07-26 12:14:39 -070035// Empty function so tests don't need to be linked against file_sync_service.cpp, which requires
Felipe Leme042c3512016-07-19 17:07:22 -070036// SELinux and its transitive dependencies...
37bool do_sync_pull(const std::vector<const char*>& srcs, const char* dst, bool copy_attrs,
38 const char* name) {
39 ADD_FAILURE() << "do_sync_pull() should have been mocked";
40 return false;
41}
42
Felipe Leme60192aa2016-07-26 12:14:39 -070043// Empty functions so tests don't need to be linked against commandline.cpp
44DefaultStandardStreamsCallback DEFAULT_STANDARD_STREAMS_CALLBACK(nullptr, nullptr);
Felipe Leme042c3512016-07-19 17:07:22 -070045int usage() {
46 return -42;
47}
Felipe Leme042c3512016-07-19 17:07:22 -070048int send_shell_command(TransportType transport_type, const char* serial, const std::string& command,
Felipe Leme60192aa2016-07-26 12:14:39 -070049 bool disable_shell_protocol, StandardStreamsCallbackInterface* callback) {
Felipe Leme042c3512016-07-19 17:07:22 -070050 ADD_FAILURE() << "send_shell_command() should have been mocked";
51 return -42;
52}
53
Felipe Leme60192aa2016-07-26 12:14:39 -070054// gmock black magic to provide a WithArg<4>(WriteOnStdout(output)) matcher
55typedef void OnStandardStreamsCallbackFunction(StandardStreamsCallbackInterface*);
56
57class OnStandardStreamsCallbackAction : public ActionInterface<OnStandardStreamsCallbackFunction> {
58 public:
59 explicit OnStandardStreamsCallbackAction(const std::string& output) : output_(output) {
60 }
61 virtual Result Perform(const ArgumentTuple& args) {
62 ::std::tr1::get<0>(args)->OnStdout(output_.c_str(), output_.size());
63 }
64
65 private:
66 std::string output_;
67};
68
69Action<OnStandardStreamsCallbackFunction> WriteOnStdout(const std::string& output) {
70 return MakeAction(new OnStandardStreamsCallbackAction(output));
71}
72
73typedef int CallbackDoneFunction(StandardStreamsCallbackInterface*);
74
75class CallbackDoneAction : public ActionInterface<CallbackDoneFunction> {
76 public:
77 virtual Result Perform(const ArgumentTuple& args) {
78 int status = ::std::tr1::get<0>(args)->Done(123); // Value passed does not matter
79 return status;
80 }
81};
82
83Action<CallbackDoneFunction> ReturnCallbackDone() {
84 return MakeAction(new CallbackDoneAction());
85}
86
Felipe Leme042c3512016-07-19 17:07:22 -070087class BugreportMock : public Bugreport {
88 public:
Felipe Leme60192aa2016-07-26 12:14:39 -070089 MOCK_METHOD5(SendShellCommand,
Felipe Leme042c3512016-07-19 17:07:22 -070090 int(TransportType transport_type, const char* serial, const std::string& command,
Felipe Leme60192aa2016-07-26 12:14:39 -070091 bool disable_shell_protocol, StandardStreamsCallbackInterface* callback));
Felipe Leme042c3512016-07-19 17:07:22 -070092 MOCK_METHOD4(DoSyncPull, bool(const std::vector<const char*>& srcs, const char* dst,
93 bool copy_attrs, const char* name));
94};
95
96class BugreportTest : public ::testing::Test {
97 public:
98 BugreportMock br_;
99};
100
101// Tests when called with invalid number of argumnts
102TEST_F(BugreportTest, InvalidNumberArgs) {
103 const char* args[1024] = {"bugreport", "to", "principal"};
104 ASSERT_EQ(-42, br_.DoIt(kTransportLocal, "HannibalLecter", 3, args));
105}
106
107// Tests the legacy 'adb bugreport' option
108TEST_F(BugreportTest, FlatFileFormat) {
Felipe Leme60192aa2016-07-26 12:14:39 -0700109 EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreport", false, _))
Felipe Leme042c3512016-07-19 17:07:22 -0700110 .WillOnce(Return(0));
111
112 const char* args[1024] = {"bugreport"};
113 ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 1, args));
114}
115
116// Tests 'adb bugreport file.zip' when it succeeds
117TEST_F(BugreportTest, Ok) {
Felipe Leme60192aa2016-07-26 12:14:39 -0700118 EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz", false, _))
119 .WillOnce(DoAll(WithArg<4>(WriteOnStdout("OK:/device/bugreport.zip")),
120 WithArg<4>(ReturnCallbackDone())));
Felipe Leme042c3512016-07-19 17:07:22 -0700121 EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
122 true, StrEq("file.zip")))
123 .WillOnce(Return(true));
124
125 const char* args[1024] = {"bugreport", "file.zip"};
126 ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
127}
128
129// Tests 'adb bugreport file' when it succeeds
130TEST_F(BugreportTest, OkNoExtension) {
Felipe Leme60192aa2016-07-26 12:14:39 -0700131 EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz", false, _))
132 .WillOnce(DoAll(WithArg<4>(WriteOnStdout("OK:/device/bugreport.zip")),
133 WithArg<4>(ReturnCallbackDone())));
Felipe Leme042c3512016-07-19 17:07:22 -0700134 EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
135 true, StrEq("file.zip")))
136 .WillOnce(Return(true));
137
138 const char* args[1024] = {"bugreport", "file"};
139 ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
140}
141
Felipe Leme60192aa2016-07-26 12:14:39 -0700142// Tests 'adb bugreport file.zip' when it succeeds but response was sent in
143// multiple buffer writers.
144TEST_F(BugreportTest, OkSplitBuffer) {
145 EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz", false, _))
146 .WillOnce(DoAll(WithArg<4>(WriteOnStdout("OK:/device")),
147 WithArg<4>(WriteOnStdout("/bugreport.zip")),
148 WithArg<4>(ReturnCallbackDone())));
149 EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
150 true, StrEq("file.zip")))
151 .WillOnce(Return(true));
152
153 const char* args[1024] = {"bugreport", "file.zip"};
154 ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
155}
156
Felipe Leme042c3512016-07-19 17:07:22 -0700157// Tests 'adb bugreport file.zip' when the bugreport itself failed
158TEST_F(BugreportTest, BugreportzReturnedFail) {
Felipe Leme60192aa2016-07-26 12:14:39 -0700159 EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz", false, _))
160 .WillOnce(DoAll(WithArg<4>(WriteOnStdout("FAIL:D'OH!")), WithArg<4>(ReturnCallbackDone())));
161
162 CaptureStderr();
163 const char* args[1024] = {"bugreport", "file.zip"};
164 ASSERT_EQ(-1, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
165 ASSERT_THAT(GetCapturedStderr(), HasSubstr("D'OH"));
166}
167
168// Tests 'adb bugreport file.zip' when the bugreport itself failed but response
169// was sent in
170// multiple buffer writes
171TEST_F(BugreportTest, BugreportzReturnedFailSplitBuffer) {
172 EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz", false, _))
173 .WillOnce(DoAll(WithArg<4>(WriteOnStdout("FAIL")), WithArg<4>(WriteOnStdout(":D'OH!")),
174 WithArg<4>(ReturnCallbackDone())));
Felipe Leme042c3512016-07-19 17:07:22 -0700175
176 CaptureStderr();
177 const char* args[1024] = {"bugreport", "file.zip"};
178 ASSERT_EQ(-1, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
179 ASSERT_THAT(GetCapturedStderr(), HasSubstr("D'OH"));
180}
181
182// Tests 'adb bugreport file.zip' when the bugreportz returned an unsupported
183// response.
184TEST_F(BugreportTest, BugreportzReturnedUnsupported) {
Felipe Leme60192aa2016-07-26 12:14:39 -0700185 EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz", false, _))
186 .WillOnce(DoAll(WithArg<4>(WriteOnStdout("bugreportz? What am I, a zombie?")),
187 WithArg<4>(ReturnCallbackDone())));
Felipe Leme042c3512016-07-19 17:07:22 -0700188
189 CaptureStderr();
190 const char* args[1024] = {"bugreport", "file.zip"};
191 ASSERT_EQ(-1, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
192 ASSERT_THAT(GetCapturedStderr(), HasSubstr("bugreportz? What am I, a zombie?"));
193}
194
195// Tests 'adb bugreport file.zip' when the bugreportz command fails
196TEST_F(BugreportTest, BugreportzFailed) {
Felipe Leme60192aa2016-07-26 12:14:39 -0700197 EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz", false, _))
Felipe Leme042c3512016-07-19 17:07:22 -0700198 .WillOnce(Return(666));
199
200 const char* args[1024] = {"bugreport", "file.zip"};
201 ASSERT_EQ(666, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
202}
203
204// Tests 'adb bugreport file.zip' when the bugreport could not be pulled
205TEST_F(BugreportTest, PullFails) {
Felipe Leme60192aa2016-07-26 12:14:39 -0700206 EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz", false, _))
207 .WillOnce(DoAll(WithArg<4>(WriteOnStdout("OK:/device/bugreport.zip")),
208 WithArg<4>(ReturnCallbackDone())));
Felipe Leme042c3512016-07-19 17:07:22 -0700209 EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
210 true, StrEq("file.zip")))
211 .WillOnce(Return(false));
212
213 const char* args[1024] = {"bugreport", "file.zip"};
214 ASSERT_EQ(1, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
215}