• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

system/corennnnn


Commit MetaInfo

Revision78e0963e4bce9cc9f0bbf0b686004ba15b1e3929 (tree)
Time2016-07-27 08:14:20
AuthorFelipe Leme <felipeal@goog...>
CommiterFelipe Leme

Log Message

Split bugreport() into its own file and added unit tests.

bugreport() will be soon refactored to track progress, which will
require more comprehensive unit tests.

As such, it's better to move it to its own files, which in turn also
requires moving send_shell_command() and usage() to commandline.h.

Fixes: 30100363
Bug: 30268737

Change-Id: I3cdf114a0b5547293320042ff0749a60886440b0

Change Summary

Incremental Difference

--- a/adb/Android.mk
+++ b/adb/Android.mk
@@ -180,6 +180,9 @@ LOCAL_CFLAGS_linux := $(LIBADB_linux_CFLAGS)
180180 LOCAL_CFLAGS_darwin := $(LIBADB_darwin_CFLAGS)
181181 LOCAL_SRC_FILES := \
182182 $(LIBADB_TEST_SRCS) \
183+ adb_client.cpp \
184+ bugreport.cpp \
185+ bugreport_test.cpp \
183186 services.cpp \
184187 shell_service_protocol.cpp \
185188 shell_service_protocol_test.cpp \
@@ -194,6 +197,7 @@ LOCAL_STATIC_LIBRARIES := \
194197 libcrypto_static \
195198 libcutils \
196199 libdiagnose_usb \
200+ libgmock_host \
197201
198202 # Set entrypoint to wmain from sysdeps_win32.cpp instead of main
199203 LOCAL_LDFLAGS_windows := -municode
@@ -240,6 +244,7 @@ LOCAL_REQUIRED_MODULES_windows := AdbWinApi AdbWinUsbApi
240244
241245 LOCAL_SRC_FILES := \
242246 adb_client.cpp \
247+ bugreport.cpp \
243248 client/main.cpp \
244249 console.cpp \
245250 commandline.cpp \
--- a/adb/adb.h
+++ b/adb/adb.h
@@ -226,8 +226,6 @@ void usb_kick(usb_handle *h);
226226 int is_adb_interface(int vid, int pid, int usb_class, int usb_subclass, int usb_protocol);
227227 #endif
228228
229-int adb_commandline(int argc, const char **argv);
230-
231229 ConnectionState connection_state(atransport *t);
232230
233231 extern const char* adb_device_banner;
--- a/adb/adb_client.h
+++ b/adb/adb_client.h
@@ -18,6 +18,7 @@
1818 #define _ADB_CLIENT_H_
1919
2020 #include "adb.h"
21+#include "sysdeps.h"
2122 #include "transport.h"
2223
2324 #include <string>
--- /dev/null
+++ b/adb/bugreport.cpp
@@ -0,0 +1,80 @@
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 <string>
18+
19+#include <android-base/strings.h>
20+
21+#include "bugreport.h"
22+#include "commandline.h"
23+#include "file_sync_service.h"
24+
25+static constexpr char BUGZ_OK_PREFIX[] = "OK:";
26+static constexpr char BUGZ_FAIL_PREFIX[] = "FAIL:";
27+
28+int Bugreport::DoIt(TransportType transport_type, const char* serial, int argc, const char** argv) {
29+ if (argc == 1) return SendShellCommand(transport_type, serial, "bugreport", false);
30+ if (argc != 2) return usage();
31+
32+ // Zipped bugreport option - will call 'bugreportz', which prints the location
33+ // of the generated
34+ // file, then pull it to the destination file provided by the user.
35+ std::string dest_file = argv[1];
36+ if (!android::base::EndsWith(argv[1], ".zip")) {
37+ // TODO: use a case-insensitive comparison (like EndsWithIgnoreCase
38+ dest_file += ".zip";
39+ }
40+ std::string output;
41+
42+ fprintf(stderr,
43+ "Bugreport is in progress and it could take minutes to complete.\n"
44+ "Please be patient and do not cancel or disconnect your device until "
45+ "it completes.\n");
46+ int status = SendShellCommand(transport_type, serial, "bugreportz", false, &output, nullptr);
47+ if (status != 0 || output.empty()) return status;
48+ output = android::base::Trim(output);
49+
50+ if (android::base::StartsWith(output, BUGZ_OK_PREFIX)) {
51+ const char* zip_file = &output[strlen(BUGZ_OK_PREFIX)];
52+ std::vector<const char*> srcs{zip_file};
53+ status = DoSyncPull(srcs, dest_file.c_str(), true, dest_file.c_str()) ? 0 : 1;
54+ if (status != 0) {
55+ fprintf(stderr, "Could not copy file '%s' to '%s'\n", zip_file, dest_file.c_str());
56+ }
57+ return status;
58+ }
59+ if (android::base::StartsWith(output, BUGZ_FAIL_PREFIX)) {
60+ const char* error_message = &output[strlen(BUGZ_FAIL_PREFIX)];
61+ fprintf(stderr, "Device failed to take a zipped bugreport: %s\n", error_message);
62+ return -1;
63+ }
64+ fprintf(stderr,
65+ "Unexpected string (%s) returned by bugreportz, "
66+ "device probably does not support it\n",
67+ output.c_str());
68+ return -1;
69+}
70+
71+int Bugreport::SendShellCommand(TransportType transport_type, const char* serial,
72+ const std::string& command, bool disable_shell_protocol,
73+ std::string* output, std::string* err) {
74+ return send_shell_command(transport_type, serial, command, disable_shell_protocol, output, err);
75+}
76+
77+bool Bugreport::DoSyncPull(const std::vector<const char*>& srcs, const char* dst, bool copy_attrs,
78+ const char* name) {
79+ return do_sync_pull(srcs, dst, copy_attrs, name);
80+}
--- /dev/null
+++ b/adb/bugreport.h
@@ -0,0 +1,44 @@
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+#ifndef BUGREPORT_H
18+#define BUGREPORT_H
19+
20+#include <vector>
21+
22+#include "adb.h"
23+
24+class Bugreport {
25+ public:
26+ Bugreport() {
27+ }
28+ int DoIt(TransportType transport_type, const char* serial, int argc, const char** argv);
29+
30+ protected:
31+ // Functions below are abstractions of external functions so they can be
32+ // mocked on tests.
33+ virtual int SendShellCommand(TransportType transport_type, const char* serial,
34+ const std::string& command, bool disable_shell_protocol,
35+ std::string* output = nullptr, std::string* err = nullptr);
36+
37+ virtual bool DoSyncPull(const std::vector<const char*>& srcs, const char* dst, bool copy_attrs,
38+ const char* name);
39+
40+ private:
41+ DISALLOW_COPY_AND_ASSIGN(Bugreport);
42+};
43+
44+#endif // BUGREPORT_H
--- /dev/null
+++ b/adb/bugreport_test.cpp
@@ -0,0 +1,155 @@
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+using ::testing::_;
23+using ::testing::DoAll;
24+using ::testing::ElementsAre;
25+using ::testing::HasSubstr;
26+using ::testing::Return;
27+using ::testing::SetArgPointee;
28+using ::testing::StrEq;
29+using ::testing::internal::CaptureStderr;
30+using ::testing::internal::GetCapturedStderr;
31+
32+// Empty function so tests don't need to be linked against
33+// file_sync_service.cpp, which requires
34+// SELinux and its transitive dependencies...
35+bool do_sync_pull(const std::vector<const char*>& srcs, const char* dst, bool copy_attrs,
36+ const char* name) {
37+ ADD_FAILURE() << "do_sync_pull() should have been mocked";
38+ return false;
39+}
40+
41+// Implemented in commandline.cpp
42+int usage() {
43+ return -42;
44+}
45+
46+// Implemented in commandline.cpp
47+int send_shell_command(TransportType transport_type, const char* serial, const std::string& command,
48+ bool disable_shell_protocol, std::string* output, std::string* err) {
49+ ADD_FAILURE() << "send_shell_command() should have been mocked";
50+ return -42;
51+}
52+
53+class BugreportMock : public Bugreport {
54+ public:
55+ MOCK_METHOD6(SendShellCommand,
56+ int(TransportType transport_type, const char* serial, const std::string& command,
57+ bool disable_shell_protocol, std::string* output, std::string* err));
58+ MOCK_METHOD4(DoSyncPull, bool(const std::vector<const char*>& srcs, const char* dst,
59+ bool copy_attrs, const char* name));
60+};
61+
62+class BugreportTest : public ::testing::Test {
63+ public:
64+ BugreportMock br_;
65+};
66+
67+// Tests when called with invalid number of argumnts
68+TEST_F(BugreportTest, InvalidNumberArgs) {
69+ const char* args[1024] = {"bugreport", "to", "principal"};
70+ ASSERT_EQ(-42, br_.DoIt(kTransportLocal, "HannibalLecter", 3, args));
71+}
72+
73+// Tests the legacy 'adb bugreport' option
74+TEST_F(BugreportTest, FlatFileFormat) {
75+ EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreport", false,
76+ nullptr, nullptr))
77+ .WillOnce(Return(0));
78+
79+ const char* args[1024] = {"bugreport"};
80+ ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 1, args));
81+}
82+
83+// Tests 'adb bugreport file.zip' when it succeeds
84+TEST_F(BugreportTest, Ok) {
85+ EXPECT_CALL(
86+ br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz", false, _, nullptr))
87+ .WillOnce(DoAll(SetArgPointee<4>("OK:/device/bugreport.zip"), Return(0)));
88+ EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
89+ true, StrEq("file.zip")))
90+ .WillOnce(Return(true));
91+
92+ const char* args[1024] = {"bugreport", "file.zip"};
93+ ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
94+}
95+
96+// Tests 'adb bugreport file' when it succeeds
97+TEST_F(BugreportTest, OkNoExtension) {
98+ EXPECT_CALL(
99+ br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz", false, _, nullptr))
100+ .WillOnce(DoAll(SetArgPointee<4>("OK:/device/bugreport.zip"), Return(0)));
101+ EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
102+ true, StrEq("file.zip")))
103+ .WillOnce(Return(true));
104+
105+ const char* args[1024] = {"bugreport", "file"};
106+ ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
107+}
108+
109+// Tests 'adb bugreport file.zip' when the bugreport itself failed
110+TEST_F(BugreportTest, BugreportzReturnedFail) {
111+ EXPECT_CALL(
112+ br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz", false, _, nullptr))
113+ .WillOnce(DoAll(SetArgPointee<4>("FAIL:D'OH!"), Return(0)));
114+
115+ CaptureStderr();
116+ const char* args[1024] = {"bugreport", "file.zip"};
117+ ASSERT_EQ(-1, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
118+ ASSERT_THAT(GetCapturedStderr(), HasSubstr("D'OH"));
119+}
120+
121+// Tests 'adb bugreport file.zip' when the bugreportz returned an unsupported
122+// response.
123+TEST_F(BugreportTest, BugreportzReturnedUnsupported) {
124+ EXPECT_CALL(
125+ br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz", false, _, nullptr))
126+ .WillOnce(DoAll(SetArgPointee<4>("bugreportz? What am I, a zombie?"), Return(0)));
127+
128+ CaptureStderr();
129+ const char* args[1024] = {"bugreport", "file.zip"};
130+ ASSERT_EQ(-1, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
131+ ASSERT_THAT(GetCapturedStderr(), HasSubstr("bugreportz? What am I, a zombie?"));
132+}
133+
134+// Tests 'adb bugreport file.zip' when the bugreportz command fails
135+TEST_F(BugreportTest, BugreportzFailed) {
136+ EXPECT_CALL(
137+ br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz", false, _, nullptr))
138+ .WillOnce(Return(666));
139+
140+ const char* args[1024] = {"bugreport", "file.zip"};
141+ ASSERT_EQ(666, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
142+}
143+
144+// Tests 'adb bugreport file.zip' when the bugreport could not be pulled
145+TEST_F(BugreportTest, PullFails) {
146+ EXPECT_CALL(
147+ br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz", false, _, nullptr))
148+ .WillOnce(DoAll(SetArgPointee<4>("OK:/device/bugreport.zip"), Return(0)));
149+ EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
150+ true, StrEq("file.zip")))
151+ .WillOnce(Return(false));
152+
153+ const char* args[1024] = {"bugreport", "file.zip"};
154+ ASSERT_EQ(1, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
155+}
--- a/adb/client/main.cpp
+++ b/adb/client/main.cpp
@@ -32,6 +32,7 @@
3232 #include "adb_auth.h"
3333 #include "adb_listeners.h"
3434 #include "adb_utils.h"
35+#include "commandline.h"
3536 #include "transport.h"
3637
3738 static std::string GetLogFilePath() {
--- a/adb/commandline.cpp
+++ b/adb/commandline.cpp
@@ -51,10 +51,11 @@
5151 #include "adb_client.h"
5252 #include "adb_io.h"
5353 #include "adb_utils.h"
54+#include "bugreport.h"
55+#include "commandline.h"
5456 #include "file_sync_service.h"
5557 #include "services.h"
5658 #include "shell_service.h"
57-#include "transport.h"
5859
5960 static int install_app(TransportType t, const char* serial, int argc, const char** argv);
6061 static int install_multiple_app(TransportType t, const char* serial, int argc, const char** argv);
@@ -65,9 +66,6 @@ static int uninstall_app_legacy(TransportType t, const char* serial, int argc, c
6566 static auto& gProductOutPath = *new std::string();
6667 extern int gListenAll;
6768
68-static constexpr char BUGZ_OK_PREFIX[] = "OK:";
69-static constexpr char BUGZ_FAIL_PREFIX[] = "FAIL:";
70-
7169 static std::string product_file(const char *extra) {
7270 if (gProductOutPath.empty()) {
7371 fprintf(stderr, "adb: Product directory not specified; "
@@ -253,7 +251,7 @@ static void help() {
253251 );
254252 }
255253
256-static int usage() {
254+int usage() {
257255 help();
258256 return 1;
259257 }
@@ -1131,13 +1129,8 @@ static bool adb_root(const char* command) {
11311129 return wait_for_device("wait-for-any", type, serial);
11321130 }
11331131
1134-// Connects to the device "shell" service with |command| and prints the
1135-// resulting output.
1136-static int send_shell_command(TransportType transport_type, const char* serial,
1137- const std::string& command,
1138- bool disable_shell_protocol,
1139- std::string* output=nullptr,
1140- std::string* err=nullptr) {
1132+int send_shell_command(TransportType transport_type, const char* serial, const std::string& command,
1133+ bool disable_shell_protocol, std::string* output, std::string* err) {
11411134 int fd;
11421135 bool use_shell_protocol = false;
11431136
@@ -1181,45 +1174,6 @@ static int send_shell_command(TransportType transport_type, const char* serial,
11811174 return exit_code;
11821175 }
11831176
1184-static int bugreport(TransportType transport_type, const char* serial, int argc,
1185- const char** argv) {
1186- if (argc == 1) return send_shell_command(transport_type, serial, "bugreport", false);
1187- if (argc != 2) return usage();
1188-
1189- // Zipped bugreport option - will call 'bugreportz', which prints the location of the generated
1190- // file, then pull it to the destination file provided by the user.
1191- std::string dest_file = argv[1];
1192- if (!android::base::EndsWith(argv[1], ".zip")) {
1193- // TODO: use a case-insensitive comparison (like EndsWithIgnoreCase
1194- dest_file += ".zip";
1195- }
1196- std::string output;
1197-
1198- fprintf(stderr, "Bugreport is in progress and it could take minutes to complete.\n"
1199- "Please be patient and do not cancel or disconnect your device until it completes.\n");
1200- int status = send_shell_command(transport_type, serial, "bugreportz", false, &output, nullptr);
1201- if (status != 0 || output.empty()) return status;
1202- output = android::base::Trim(output);
1203-
1204- if (android::base::StartsWith(output, BUGZ_OK_PREFIX)) {
1205- const char* zip_file = &output[strlen(BUGZ_OK_PREFIX)];
1206- std::vector<const char*> srcs{zip_file};
1207- status = do_sync_pull(srcs, dest_file.c_str(), true, dest_file.c_str()) ? 0 : 1;
1208- if (status != 0) {
1209- fprintf(stderr, "Could not copy file '%s' to '%s'\n", zip_file, dest_file.c_str());
1210- }
1211- return status;
1212- }
1213- if (android::base::StartsWith(output, BUGZ_FAIL_PREFIX)) {
1214- const char* error_message = &output[strlen(BUGZ_FAIL_PREFIX)];
1215- fprintf(stderr, "Device failed to take a zipped bugreport: %s\n", error_message);
1216- return -1;
1217- }
1218- fprintf(stderr, "Unexpected string (%s) returned by bugreportz, "
1219- "device probably does not support -z option\n", output.c_str());
1220- return -1;
1221-}
1222-
12231177 static int logcat(TransportType transport, const char* serial, int argc, const char** argv) {
12241178 char* log_tags = getenv("ANDROID_LOG_TAGS");
12251179 std::string quoted = escape_arg(log_tags == nullptr ? "" : log_tags);
@@ -1775,7 +1729,8 @@ int adb_commandline(int argc, const char **argv) {
17751729 } else if (!strcmp(argv[0], "root") || !strcmp(argv[0], "unroot")) {
17761730 return adb_root(argv[0]) ? 0 : 1;
17771731 } else if (!strcmp(argv[0], "bugreport")) {
1778- return bugreport(transport_type, serial, argc, argv);
1732+ Bugreport bugreport;
1733+ return bugreport.DoIt(transport_type, serial, argc, argv);
17791734 } else if (!strcmp(argv[0], "forward") || !strcmp(argv[0], "reverse")) {
17801735 bool reverse = !strcmp(argv[0], "reverse");
17811736 ++argv;
--- /dev/null
+++ b/adb/commandline.h
@@ -0,0 +1,31 @@
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+#ifndef COMMANDLINE_H
18+#define COMMANDLINE_H
19+
20+#include "adb.h"
21+
22+int adb_commandline(int argc, const char** argv);
23+int usage();
24+
25+// Connects to the device "shell" service with |command| and prints the
26+// resulting output.
27+int send_shell_command(TransportType transport_type, const char* serial, const std::string& command,
28+ bool disable_shell_protocol, std::string* output = nullptr,
29+ std::string* err = nullptr);
30+
31+#endif // COMMANDLINE_H