blob: fdeea24da4b19b66ea4dc12c456822074c434c81 [file] [log] [blame]
Felipe Leme4c2d6632016-09-28 14:32:00 -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
Felipe Leme75876a22016-10-27 16:31:27 -070017#define LOG_TAG "dumpstate"
18#include <cutils/log.h>
19
Felipe Lemef0292972016-11-22 13:57:05 -080020#include "DumpstateInternal.h"
Felipe Leme75876a22016-10-27 16:31:27 -070021#include "DumpstateService.h"
22#include "android/os/BnDumpstate.h"
Felipe Leme4c2d6632016-09-28 14:32:00 -070023#include "dumpstate.h"
Rhed Jao27077b12020-07-14 18:38:08 +080024#include "DumpPool.h"
Felipe Leme4c2d6632016-09-28 14:32:00 -070025
26#include <gmock/gmock.h>
27#include <gtest/gtest.h>
28
Felipe Leme46b85da2016-11-21 17:40:45 -080029#include <fcntl.h>
Felipe Leme4c2d6632016-09-28 14:32:00 -070030#include <libgen.h>
Felipe Lemefd8affa2016-09-30 17:38:57 -070031#include <signal.h>
32#include <sys/types.h>
Felipe Leme4c2d6632016-09-28 14:32:00 -070033#include <unistd.h>
Felipe Lemefd8affa2016-09-30 17:38:57 -070034#include <thread>
Felipe Leme4c2d6632016-09-28 14:32:00 -070035
36#include <android-base/file.h>
Felipe Lemed80e6b62016-10-03 13:08:14 -070037#include <android-base/properties.h>
38#include <android-base/stringprintf.h>
Felipe Lemefd8affa2016-09-30 17:38:57 -070039#include <android-base/strings.h>
Abhijeet Kaure370d682019-10-01 16:49:30 +010040#include <android-base/unique_fd.h>
Hunter Knepshield8540faf2020-02-04 19:47:20 -080041#include <android/hardware/dumpstate/1.1/types.h>
42#include <cutils/properties.h>
Felipe Leme4c2d6632016-09-28 14:32:00 -070043
Felipe Leme47e9be22016-12-21 15:37:07 -080044namespace android {
45namespace os {
46namespace dumpstate {
Felipe Lemed80e6b62016-10-03 13:08:14 -070047
Hunter Knepshield8540faf2020-02-04 19:47:20 -080048using ::android::hardware::dumpstate::V1_1::DumpstateMode;
Felipe Leme4c2d6632016-09-28 14:32:00 -070049using ::testing::EndsWith;
Rhed Jao27077b12020-07-14 18:38:08 +080050using ::testing::Eq;
Felipe Leme46b85da2016-11-21 17:40:45 -080051using ::testing::HasSubstr;
Felipe Leme4c2d6632016-09-28 14:32:00 -070052using ::testing::IsEmpty;
Hunter Knepshield8540faf2020-02-04 19:47:20 -080053using ::testing::IsNull;
Felipe Leme009ecbb2016-11-07 10:18:44 -080054using ::testing::NotNull;
Felipe Leme4c2d6632016-09-28 14:32:00 -070055using ::testing::StartsWith;
Hunter Knepshield8540faf2020-02-04 19:47:20 -080056using ::testing::StrEq;
Felipe Leme4c2d6632016-09-28 14:32:00 -070057using ::testing::Test;
58using ::testing::internal::CaptureStderr;
59using ::testing::internal::CaptureStdout;
60using ::testing::internal::GetCapturedStderr;
61using ::testing::internal::GetCapturedStdout;
62
Nandana Dutt3f8c7172018-09-25 12:01:54 +010063#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
64
Felipe Leme75876a22016-10-27 16:31:27 -070065class DumpstateListenerMock : public IDumpstateListener {
66 public:
Nandana Dutta6a28bd2019-01-14 16:54:38 +000067 MOCK_METHOD1(onProgress, binder::Status(int32_t progress));
68 MOCK_METHOD1(onError, binder::Status(int32_t error_code));
Nandana Duttcc4ead82019-01-23 08:29:23 +000069 MOCK_METHOD0(onFinished, binder::Status());
Paul Chang0d2aad72020-02-13 20:04:03 +080070 MOCK_METHOD1(onScreenshotTaken, binder::Status(bool success));
Paul Chang5702b482020-05-28 22:05:47 +080071 MOCK_METHOD0(onUiIntensiveBugreportDumpsFinished, binder::Status());
Felipe Leme75876a22016-10-27 16:31:27 -070072
73 protected:
74 MOCK_METHOD0(onAsBinder, IBinder*());
75};
76
Felipe Leme46b85da2016-11-21 17:40:45 -080077static int calls_;
78
Felipe Leme7447d7c2016-11-03 18:12:22 -070079// Base class for all tests in this file
80class DumpstateBaseTest : public Test {
Felipe Leme46b85da2016-11-21 17:40:45 -080081 public:
82 virtual void SetUp() override {
83 calls_++;
Felipe Lemef0292972016-11-22 13:57:05 -080084 SetDryRun(false);
Felipe Leme46b85da2016-11-21 17:40:45 -080085 }
86
Felipe Lemef0292972016-11-22 13:57:05 -080087 void SetDryRun(bool dry_run) const {
88 PropertiesHelper::dry_run_ = dry_run;
89 }
90
91 void SetBuildType(const std::string& build_type) const {
92 PropertiesHelper::build_type_ = build_type;
93 }
94
Nandana Dutt4b392be2018-11-02 16:17:05 +000095 void SetUnroot(bool unroot) const {
96 PropertiesHelper::unroot_ = unroot;
97 }
98
Rhed Jao1c855122020-07-16 17:37:39 +080099 void SetParallelRun(bool parallel_run) const {
100 PropertiesHelper::parallel_run_ = parallel_run;
101 }
102
Felipe Lemef0292972016-11-22 13:57:05 -0800103 bool IsStandalone() const {
Felipe Leme46b85da2016-11-21 17:40:45 -0800104 return calls_ == 1;
105 }
106
Felipe Lemef0292972016-11-22 13:57:05 -0800107 void DropRoot() const {
108 DropRootUser();
Felipe Leme46b85da2016-11-21 17:40:45 -0800109 uid_t uid = getuid();
110 ASSERT_EQ(2000, (int)uid);
111 }
112
Felipe Leme7447d7c2016-11-03 18:12:22 -0700113 protected:
114 const std::string kTestPath = dirname(android::base::GetExecutablePath().c_str());
Dan Shie177e8e2019-06-20 11:08:14 -0700115 const std::string kTestDataPath = kTestPath + "/tests/testdata/";
116 const std::string kSimpleCommand = kTestPath + "/dumpstate_test_fixture";
Felipe Leme7447d7c2016-11-03 18:12:22 -0700117 const std::string kEchoCommand = "/system/bin/echo";
118
119 /*
120 * Copies a text file fixture to a temporary file, returning it's path.
121 *
122 * Useful in cases where the test case changes the content of the tile.
123 */
124 std::string CopyTextFileFixture(const std::string& relative_name) {
125 std::string from = kTestDataPath + relative_name;
126 // Not using TemporaryFile because it's deleted at the end, and it's useful to keep it
127 // around for poking when the test fails.
128 std::string to = kTestDataPath + relative_name + ".tmp";
129 ALOGD("CopyTextFileFixture: from %s to %s\n", from.c_str(), to.c_str());
130 android::base::RemoveFileIfExists(to);
131 CopyTextFile(from, to);
132 return to.c_str();
133 }
134
Felipe Leme46b85da2016-11-21 17:40:45 -0800135 // Need functions that returns void to use assertions -
Felipe Leme7447d7c2016-11-03 18:12:22 -0700136 // https://github.com/google/googletest/blob/master/googletest/docs/AdvancedGuide.md#assertion-placement
Felipe Leme46b85da2016-11-21 17:40:45 -0800137 void ReadFileToString(const std::string& path, std::string* content) {
138 ASSERT_TRUE(android::base::ReadFileToString(path, content))
139 << "could not read contents from " << path;
140 }
141 void WriteStringToFile(const std::string& content, const std::string& path) {
142 ASSERT_TRUE(android::base::WriteStringToFile(content, path))
143 << "could not write contents to " << path;
144 }
145
146 private:
Felipe Leme7447d7c2016-11-03 18:12:22 -0700147 void CopyTextFile(const std::string& from, const std::string& to) {
148 std::string content;
Felipe Leme46b85da2016-11-21 17:40:45 -0800149 ReadFileToString(from, &content);
150 WriteStringToFile(content, to);
Felipe Leme7447d7c2016-11-03 18:12:22 -0700151 }
152};
153
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100154class DumpOptionsTest : public Test {
155 public:
156 virtual ~DumpOptionsTest() {
157 }
158 virtual void SetUp() {
159 options_ = Dumpstate::DumpOptions();
160 }
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000161 void TearDown() {
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000162 }
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100163 Dumpstate::DumpOptions options_;
Abhijeet Kaure370d682019-10-01 16:49:30 +0100164 android::base::unique_fd fd;
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100165};
166
167TEST_F(DumpOptionsTest, InitializeNone) {
168 // clang-format off
169 char* argv[] = {
170 const_cast<char*>("dumpstate")
171 };
172 // clang-format on
173
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100174 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
175
176 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
Nandana Dutt58d72e22018-11-16 10:30:48 +0000177
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100178 EXPECT_FALSE(options_.do_add_date);
179 EXPECT_FALSE(options_.do_zip_file);
mhasank3a4cfb42020-06-15 18:06:43 -0700180 EXPECT_EQ("", options_.out_dir);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100181 EXPECT_FALSE(options_.use_socket);
182 EXPECT_FALSE(options_.use_control_socket);
183 EXPECT_FALSE(options_.show_header_only);
184 EXPECT_TRUE(options_.do_vibrate);
Paul Chang0d2aad72020-02-13 20:04:03 +0800185 EXPECT_FALSE(options_.do_screenshot);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100186 EXPECT_FALSE(options_.do_progress_updates);
187 EXPECT_FALSE(options_.is_remote_mode);
mhasankd451a472020-05-26 18:02:39 -0700188 EXPECT_FALSE(options_.limited_only);
Hunter Knepshield8540faf2020-02-04 19:47:20 -0800189 EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::DEFAULT);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000190}
191
192TEST_F(DumpOptionsTest, InitializeAdbBugreport) {
193 // clang-format off
194 char* argv[] = {
195 const_cast<char*>("dumpstatez"),
196 const_cast<char*>("-S"),
197 const_cast<char*>("-d"),
198 const_cast<char*>("-z"),
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000199 };
200 // clang-format on
201
202 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
203
204 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
205 EXPECT_TRUE(options_.do_add_date);
206 EXPECT_TRUE(options_.do_zip_file);
207 EXPECT_TRUE(options_.use_control_socket);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000208
209 // Other options retain default values
210 EXPECT_TRUE(options_.do_vibrate);
211 EXPECT_FALSE(options_.show_header_only);
Paul Chang0d2aad72020-02-13 20:04:03 +0800212 EXPECT_FALSE(options_.do_screenshot);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000213 EXPECT_FALSE(options_.do_progress_updates);
214 EXPECT_FALSE(options_.is_remote_mode);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000215 EXPECT_FALSE(options_.use_socket);
mhasankd451a472020-05-26 18:02:39 -0700216 EXPECT_FALSE(options_.limited_only);
Hunter Knepshield8540faf2020-02-04 19:47:20 -0800217 EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::DEFAULT);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000218}
219
220TEST_F(DumpOptionsTest, InitializeAdbShellBugreport) {
221 // clang-format off
222 char* argv[] = {
223 const_cast<char*>("dumpstate"),
224 const_cast<char*>("-s"),
225 };
226 // clang-format on
227
228 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
229
230 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
231 EXPECT_TRUE(options_.use_socket);
232
233 // Other options retain default values
234 EXPECT_TRUE(options_.do_vibrate);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000235 EXPECT_FALSE(options_.do_add_date);
236 EXPECT_FALSE(options_.do_zip_file);
237 EXPECT_FALSE(options_.use_control_socket);
238 EXPECT_FALSE(options_.show_header_only);
Paul Chang0d2aad72020-02-13 20:04:03 +0800239 EXPECT_FALSE(options_.do_screenshot);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000240 EXPECT_FALSE(options_.do_progress_updates);
241 EXPECT_FALSE(options_.is_remote_mode);
mhasankd451a472020-05-26 18:02:39 -0700242 EXPECT_FALSE(options_.limited_only);
Hunter Knepshield8540faf2020-02-04 19:47:20 -0800243 EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::DEFAULT);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000244}
245
246TEST_F(DumpOptionsTest, InitializeFullBugReport) {
Paul Changf59c2b72020-03-10 02:08:55 +0800247 options_.Initialize(Dumpstate::BugreportMode::BUGREPORT_FULL, fd, fd, true);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000248 EXPECT_TRUE(options_.do_add_date);
Paul Chang0d2aad72020-02-13 20:04:03 +0800249 EXPECT_TRUE(options_.do_screenshot);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000250 EXPECT_TRUE(options_.do_zip_file);
Hunter Knepshield8540faf2020-02-04 19:47:20 -0800251 EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::FULL);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000252
253 // Other options retain default values
254 EXPECT_TRUE(options_.do_vibrate);
255 EXPECT_FALSE(options_.use_control_socket);
256 EXPECT_FALSE(options_.show_header_only);
257 EXPECT_FALSE(options_.do_progress_updates);
258 EXPECT_FALSE(options_.is_remote_mode);
259 EXPECT_FALSE(options_.use_socket);
mhasankd451a472020-05-26 18:02:39 -0700260 EXPECT_FALSE(options_.limited_only);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000261}
262
263TEST_F(DumpOptionsTest, InitializeInteractiveBugReport) {
Paul Changf59c2b72020-03-10 02:08:55 +0800264 options_.Initialize(Dumpstate::BugreportMode::BUGREPORT_INTERACTIVE, fd, fd, true);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000265 EXPECT_TRUE(options_.do_add_date);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000266 EXPECT_TRUE(options_.do_zip_file);
267 EXPECT_TRUE(options_.do_progress_updates);
Paul Chang0d2aad72020-02-13 20:04:03 +0800268 EXPECT_TRUE(options_.do_screenshot);
Hunter Knepshield8540faf2020-02-04 19:47:20 -0800269 EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::INTERACTIVE);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000270
271 // Other options retain default values
272 EXPECT_TRUE(options_.do_vibrate);
273 EXPECT_FALSE(options_.use_control_socket);
274 EXPECT_FALSE(options_.show_header_only);
275 EXPECT_FALSE(options_.is_remote_mode);
276 EXPECT_FALSE(options_.use_socket);
mhasankd451a472020-05-26 18:02:39 -0700277 EXPECT_FALSE(options_.limited_only);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000278}
279
280TEST_F(DumpOptionsTest, InitializeRemoteBugReport) {
Paul Changf59c2b72020-03-10 02:08:55 +0800281 options_.Initialize(Dumpstate::BugreportMode::BUGREPORT_REMOTE, fd, fd, false);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000282 EXPECT_TRUE(options_.do_add_date);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000283 EXPECT_TRUE(options_.do_zip_file);
284 EXPECT_TRUE(options_.is_remote_mode);
285 EXPECT_FALSE(options_.do_vibrate);
Paul Chang0d2aad72020-02-13 20:04:03 +0800286 EXPECT_FALSE(options_.do_screenshot);
Hunter Knepshield8540faf2020-02-04 19:47:20 -0800287 EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::REMOTE);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000288
289 // Other options retain default values
290 EXPECT_FALSE(options_.use_control_socket);
291 EXPECT_FALSE(options_.show_header_only);
292 EXPECT_FALSE(options_.do_progress_updates);
293 EXPECT_FALSE(options_.use_socket);
mhasankd451a472020-05-26 18:02:39 -0700294 EXPECT_FALSE(options_.limited_only);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000295}
296
297TEST_F(DumpOptionsTest, InitializeWearBugReport) {
Paul Changf59c2b72020-03-10 02:08:55 +0800298 options_.Initialize(Dumpstate::BugreportMode::BUGREPORT_WEAR, fd, fd, true);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000299 EXPECT_TRUE(options_.do_add_date);
Paul Chang0d2aad72020-02-13 20:04:03 +0800300 EXPECT_TRUE(options_.do_screenshot);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000301 EXPECT_TRUE(options_.do_zip_file);
302 EXPECT_TRUE(options_.do_progress_updates);
Hunter Knepshield8540faf2020-02-04 19:47:20 -0800303 EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::WEAR);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000304
305 // Other options retain default values
306 EXPECT_TRUE(options_.do_vibrate);
307 EXPECT_FALSE(options_.use_control_socket);
308 EXPECT_FALSE(options_.show_header_only);
309 EXPECT_FALSE(options_.is_remote_mode);
310 EXPECT_FALSE(options_.use_socket);
mhasankd451a472020-05-26 18:02:39 -0700311 EXPECT_FALSE(options_.limited_only);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000312}
313
314TEST_F(DumpOptionsTest, InitializeTelephonyBugReport) {
Paul Changf59c2b72020-03-10 02:08:55 +0800315 options_.Initialize(Dumpstate::BugreportMode::BUGREPORT_TELEPHONY, fd, fd, false);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000316 EXPECT_TRUE(options_.do_add_date);
Paul Chang0d2aad72020-02-13 20:04:03 +0800317 EXPECT_FALSE(options_.do_screenshot);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000318 EXPECT_TRUE(options_.do_zip_file);
319 EXPECT_TRUE(options_.telephony_only);
Hunter Knepshield820f9bc2020-02-05 20:10:53 -0800320 EXPECT_TRUE(options_.do_progress_updates);
Hunter Knepshield8540faf2020-02-04 19:47:20 -0800321 EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::CONNECTIVITY);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000322
323 // Other options retain default values
324 EXPECT_TRUE(options_.do_vibrate);
325 EXPECT_FALSE(options_.use_control_socket);
326 EXPECT_FALSE(options_.show_header_only);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000327 EXPECT_FALSE(options_.is_remote_mode);
328 EXPECT_FALSE(options_.use_socket);
mhasankd451a472020-05-26 18:02:39 -0700329 EXPECT_FALSE(options_.limited_only);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000330}
331
332TEST_F(DumpOptionsTest, InitializeWifiBugReport) {
Paul Changf59c2b72020-03-10 02:08:55 +0800333 options_.Initialize(Dumpstate::BugreportMode::BUGREPORT_WIFI, fd, fd, false);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000334 EXPECT_TRUE(options_.do_add_date);
Paul Chang0d2aad72020-02-13 20:04:03 +0800335 EXPECT_FALSE(options_.do_screenshot);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000336 EXPECT_TRUE(options_.do_zip_file);
337 EXPECT_TRUE(options_.wifi_only);
Hunter Knepshield8540faf2020-02-04 19:47:20 -0800338 EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::WIFI);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000339
340 // Other options retain default values
341 EXPECT_TRUE(options_.do_vibrate);
342 EXPECT_FALSE(options_.use_control_socket);
343 EXPECT_FALSE(options_.show_header_only);
344 EXPECT_FALSE(options_.do_progress_updates);
345 EXPECT_FALSE(options_.is_remote_mode);
346 EXPECT_FALSE(options_.use_socket);
mhasankd451a472020-05-26 18:02:39 -0700347 EXPECT_FALSE(options_.limited_only);
348}
349
350TEST_F(DumpOptionsTest, InitializeLimitedOnlyBugreport) {
351 // clang-format off
352 char* argv[] = {
353 const_cast<char*>("dumpstatez"),
354 const_cast<char*>("-S"),
355 const_cast<char*>("-d"),
356 const_cast<char*>("-z"),
357 const_cast<char*>("-q"),
mhasank2d75c442020-06-11 15:05:25 -0700358 const_cast<char*>("-L"),
359 const_cast<char*>("-o abc")
mhasankd451a472020-05-26 18:02:39 -0700360 };
361 // clang-format on
362
363 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
364
365 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
366 EXPECT_TRUE(options_.do_add_date);
367 EXPECT_TRUE(options_.do_zip_file);
368 EXPECT_TRUE(options_.use_control_socket);
369 EXPECT_FALSE(options_.do_vibrate);
370 EXPECT_TRUE(options_.limited_only);
mhasank3a4cfb42020-06-15 18:06:43 -0700371 EXPECT_EQ(" abc", std::string(options_.out_dir));
mhasankd451a472020-05-26 18:02:39 -0700372
373 // Other options retain default values
374 EXPECT_FALSE(options_.show_header_only);
375 EXPECT_FALSE(options_.do_screenshot);
376 EXPECT_FALSE(options_.do_progress_updates);
377 EXPECT_FALSE(options_.is_remote_mode);
378 EXPECT_FALSE(options_.use_socket);
379 EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::DEFAULT);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000380}
381
382TEST_F(DumpOptionsTest, InitializeDefaultBugReport) {
383 // default: commandline options are not overridden
384 // clang-format off
385 char* argv[] = {
386 const_cast<char*>("bugreport"),
387 const_cast<char*>("-d"),
388 const_cast<char*>("-p"),
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000389 const_cast<char*>("-z"),
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000390 };
391 // clang-format on
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000392 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
393
394 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
395 EXPECT_TRUE(options_.do_add_date);
Paul Chang0d2aad72020-02-13 20:04:03 +0800396 EXPECT_TRUE(options_.do_screenshot);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000397 EXPECT_TRUE(options_.do_zip_file);
Hunter Knepshield8540faf2020-02-04 19:47:20 -0800398 EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::DEFAULT);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000399
400 // Other options retain default values
401 EXPECT_TRUE(options_.do_vibrate);
402 EXPECT_FALSE(options_.use_control_socket);
403 EXPECT_FALSE(options_.show_header_only);
404 EXPECT_FALSE(options_.do_progress_updates);
405 EXPECT_FALSE(options_.is_remote_mode);
406 EXPECT_FALSE(options_.use_socket);
407 EXPECT_FALSE(options_.wifi_only);
mhasankd451a472020-05-26 18:02:39 -0700408 EXPECT_FALSE(options_.limited_only);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100409}
410
411TEST_F(DumpOptionsTest, InitializePartial1) {
412 // clang-format off
413 char* argv[] = {
414 const_cast<char*>("dumpstate"),
415 const_cast<char*>("-d"),
416 const_cast<char*>("-z"),
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100417 const_cast<char*>("-s"),
418 const_cast<char*>("-S"),
419
420 };
421 // clang-format on
422
423 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
424
425 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
426 EXPECT_TRUE(options_.do_add_date);
427 EXPECT_TRUE(options_.do_zip_file);
428 // TODO: Maybe we should trim the filename
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100429 EXPECT_TRUE(options_.use_socket);
430 EXPECT_TRUE(options_.use_control_socket);
431
432 // Other options retain default values
433 EXPECT_FALSE(options_.show_header_only);
434 EXPECT_TRUE(options_.do_vibrate);
Paul Chang0d2aad72020-02-13 20:04:03 +0800435 EXPECT_FALSE(options_.do_screenshot);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100436 EXPECT_FALSE(options_.do_progress_updates);
437 EXPECT_FALSE(options_.is_remote_mode);
mhasankd451a472020-05-26 18:02:39 -0700438 EXPECT_FALSE(options_.limited_only);
Hunter Knepshield8540faf2020-02-04 19:47:20 -0800439 EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::DEFAULT);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100440}
441
442TEST_F(DumpOptionsTest, InitializePartial2) {
443 // clang-format off
444 char* argv[] = {
445 const_cast<char*>("dumpstate"),
446 const_cast<char*>("-v"),
447 const_cast<char*>("-q"),
448 const_cast<char*>("-p"),
449 const_cast<char*>("-P"),
450 const_cast<char*>("-R"),
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100451 };
452 // clang-format on
453
454 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
455
456 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
457 EXPECT_TRUE(options_.show_header_only);
458 EXPECT_FALSE(options_.do_vibrate);
Paul Chang0d2aad72020-02-13 20:04:03 +0800459 EXPECT_TRUE(options_.do_screenshot);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100460 EXPECT_TRUE(options_.do_progress_updates);
461 EXPECT_TRUE(options_.is_remote_mode);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100462
463 // Other options retain default values
464 EXPECT_FALSE(options_.do_add_date);
465 EXPECT_FALSE(options_.do_zip_file);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100466 EXPECT_FALSE(options_.use_socket);
467 EXPECT_FALSE(options_.use_control_socket);
mhasankd451a472020-05-26 18:02:39 -0700468 EXPECT_FALSE(options_.limited_only);
Hunter Knepshield8540faf2020-02-04 19:47:20 -0800469 EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::DEFAULT);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100470}
471
472TEST_F(DumpOptionsTest, InitializeHelp) {
473 // clang-format off
474 char* argv[] = {
475 const_cast<char*>("dumpstate"),
476 const_cast<char*>("-h")
477 };
478 // clang-format on
479
480 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
481
482 // -h is for help.
483 EXPECT_EQ(status, Dumpstate::RunStatus::HELP);
484}
485
486TEST_F(DumpOptionsTest, InitializeUnknown) {
487 // clang-format off
488 char* argv[] = {
489 const_cast<char*>("dumpstate"),
490 const_cast<char*>("-u") // unknown flag
491 };
492 // clang-format on
493
494 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
495
496 // -u is unknown.
497 EXPECT_EQ(status, Dumpstate::RunStatus::INVALID_INPUT);
498}
499
500TEST_F(DumpOptionsTest, ValidateOptionsNeedOutfile1) {
501 options_.do_zip_file = true;
Nandana Dutt9a76d202019-01-21 15:56:48 +0000502 // Writing to socket = !writing to file.
503 options_.use_socket = true;
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100504 EXPECT_FALSE(options_.ValidateOptions());
Nandana Dutt9a76d202019-01-21 15:56:48 +0000505
506 options_.use_socket = false;
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100507 EXPECT_TRUE(options_.ValidateOptions());
508}
509
510TEST_F(DumpOptionsTest, ValidateOptionsNeedOutfile2) {
Abhijeet Kaure370d682019-10-01 16:49:30 +0100511 options_.do_progress_updates = true;
Nandana Dutt9a76d202019-01-21 15:56:48 +0000512 // Writing to socket = !writing to file.
513 options_.use_socket = true;
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100514 EXPECT_FALSE(options_.ValidateOptions());
Nandana Dutt9a76d202019-01-21 15:56:48 +0000515
516 options_.use_socket = false;
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100517 EXPECT_TRUE(options_.ValidateOptions());
518}
519
520TEST_F(DumpOptionsTest, ValidateOptionsNeedZipfile) {
521 options_.use_control_socket = true;
522 EXPECT_FALSE(options_.ValidateOptions());
523
524 options_.do_zip_file = true;
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100525 EXPECT_TRUE(options_.ValidateOptions());
526}
527
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100528TEST_F(DumpOptionsTest, ValidateOptionsRemoteMode) {
529 options_.is_remote_mode = true;
530 EXPECT_FALSE(options_.ValidateOptions());
531
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100532 options_.do_zip_file = true;
533 options_.do_add_date = true;
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100534 EXPECT_TRUE(options_.ValidateOptions());
535}
536
Felipe Leme7447d7c2016-11-03 18:12:22 -0700537class DumpstateTest : public DumpstateBaseTest {
Felipe Leme4c2d6632016-09-28 14:32:00 -0700538 public:
539 void SetUp() {
Felipe Leme46b85da2016-11-21 17:40:45 -0800540 DumpstateBaseTest::SetUp();
Felipe Leme4c2d6632016-09-28 14:32:00 -0700541 SetDryRun(false);
Felipe Lemed80e6b62016-10-03 13:08:14 -0700542 SetBuildType(android::base::GetProperty("ro.build.type", "(unknown)"));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700543 ds.progress_.reset(new Progress());
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100544 ds.options_.reset(new Dumpstate::DumpOptions());
Felipe Leme4c2d6632016-09-28 14:32:00 -0700545 }
546
Rhed Jao1c855122020-07-16 17:37:39 +0800547 void TearDown() {
548 ds.ShutdownDumpPool();
549 }
550
Felipe Leme4c2d6632016-09-28 14:32:00 -0700551 // Runs a command and capture `stdout` and `stderr`.
Felipe Leme9a523ae2016-10-20 15:10:33 -0700552 int RunCommand(const std::string& title, const std::vector<std::string>& full_command,
Felipe Leme4c2d6632016-09-28 14:32:00 -0700553 const CommandOptions& options = CommandOptions::DEFAULT) {
554 CaptureStdout();
555 CaptureStderr();
Felipe Leme9a523ae2016-10-20 15:10:33 -0700556 int status = ds.RunCommand(title, full_command, options);
Felipe Leme4c2d6632016-09-28 14:32:00 -0700557 out = GetCapturedStdout();
558 err = GetCapturedStderr();
559 return status;
560 }
561
Felipe Lemecef02982016-10-03 17:22:22 -0700562 // Dumps a file and capture `stdout` and `stderr`.
563 int DumpFile(const std::string& title, const std::string& path) {
564 CaptureStdout();
565 CaptureStderr();
566 int status = ds.DumpFile(title, path);
567 out = GetCapturedStdout();
568 err = GetCapturedStderr();
569 return status;
570 }
571
Nandana Dutt402a8392019-06-14 14:25:13 +0100572 void SetProgress(long progress, long initial_max) {
573 ds.last_reported_percent_progress_ = 0;
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100574 ds.options_->do_progress_updates = true;
Felipe Leme7447d7c2016-11-03 18:12:22 -0700575 ds.progress_.reset(new Progress(initial_max, progress, 1.2));
576 }
577
Rhed Jao1c855122020-07-16 17:37:39 +0800578 void EnableParallelRunIfNeeded() {
579 ds.EnableParallelRunIfNeeded();
580 }
581
Abhijeet Kaured5d6a62019-10-07 15:02:05 +0100582 std::string GetProgressMessage(int progress, int max,
583 int old_max = 0, bool update_progress = true) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700584 EXPECT_EQ(progress, ds.progress_->Get()) << "invalid progress";
585 EXPECT_EQ(max, ds.progress_->GetMax()) << "invalid max";
Felipe Leme75876a22016-10-27 16:31:27 -0700586
Felipe Leme7447d7c2016-11-03 18:12:22 -0700587 bool max_increased = old_max > 0;
Felipe Leme75876a22016-10-27 16:31:27 -0700588
Felipe Leme009ecbb2016-11-07 10:18:44 -0800589 std::string message = "";
Felipe Leme75876a22016-10-27 16:31:27 -0700590 if (max_increased) {
Felipe Leme009ecbb2016-11-07 10:18:44 -0800591 message =
Felipe Leme7447d7c2016-11-03 18:12:22 -0700592 android::base::StringPrintf("Adjusting max progress from %d to %d\n", old_max, max);
Felipe Leme75876a22016-10-27 16:31:27 -0700593 }
594
Felipe Leme009ecbb2016-11-07 10:18:44 -0800595 if (update_progress) {
Abhijeet Kaured5d6a62019-10-07 15:02:05 +0100596 message += android::base::StringPrintf("Setting progress: %d/%d (%d%%)\n",
597 progress, max, (100 * progress / max));
Felipe Leme009ecbb2016-11-07 10:18:44 -0800598 }
599
600 return message;
Felipe Lemed80e6b62016-10-03 13:08:14 -0700601 }
602
Felipe Leme4c2d6632016-09-28 14:32:00 -0700603 // `stdout` and `stderr` from the last command ran.
604 std::string out, err;
605
Felipe Lemefd8affa2016-09-30 17:38:57 -0700606 Dumpstate& ds = Dumpstate::GetInstance();
Felipe Leme4c2d6632016-09-28 14:32:00 -0700607};
608
609TEST_F(DumpstateTest, RunCommandNoArgs) {
610 EXPECT_EQ(-1, RunCommand("", {}));
611}
612
613TEST_F(DumpstateTest, RunCommandNoTitle) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700614 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700615 EXPECT_THAT(out, StrEq("stdout\n"));
616 EXPECT_THAT(err, StrEq("stderr\n"));
617}
618
619TEST_F(DumpstateTest, RunCommandWithTitle) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700620 EXPECT_EQ(0, RunCommand("I AM GROOT", {kSimpleCommand}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700621 EXPECT_THAT(err, StrEq("stderr\n"));
Greg Kaiser3a811c12019-05-21 12:48:59 -0700622 // The duration may not get output, depending on how long it takes,
623 // so we just check the prefix.
Felipe Lemefd8affa2016-09-30 17:38:57 -0700624 EXPECT_THAT(out,
Nandana Dutt47527b52019-03-29 15:34:36 +0000625 StartsWith("------ I AM GROOT (" + kSimpleCommand + ") ------\nstdout\n"));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700626}
627
Felipe Lemefd8affa2016-09-30 17:38:57 -0700628TEST_F(DumpstateTest, RunCommandWithLoggingMessage) {
Felipe Leme4c2d6632016-09-28 14:32:00 -0700629 EXPECT_EQ(
Felipe Leme7447d7c2016-11-03 18:12:22 -0700630 0, RunCommand("", {kSimpleCommand},
Felipe Lemefd8affa2016-09-30 17:38:57 -0700631 CommandOptions::WithTimeout(10).Log("COMMAND, Y U NO LOG FIRST?").Build()));
632 EXPECT_THAT(out, StrEq("stdout\n"));
633 EXPECT_THAT(err, StrEq("COMMAND, Y U NO LOG FIRST?stderr\n"));
634}
635
636TEST_F(DumpstateTest, RunCommandRedirectStderr) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700637 EXPECT_EQ(0, RunCommand("", {kSimpleCommand},
Felipe Lemefd8affa2016-09-30 17:38:57 -0700638 CommandOptions::WithTimeout(10).RedirectStderr().Build()));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700639 EXPECT_THAT(out, IsEmpty());
Felipe Lemefd8affa2016-09-30 17:38:57 -0700640 EXPECT_THAT(err, StrEq("stdout\nstderr\n"));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700641}
642
643TEST_F(DumpstateTest, RunCommandWithOneArg) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700644 EXPECT_EQ(0, RunCommand("", {kEchoCommand, "one"}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700645 EXPECT_THAT(err, IsEmpty());
646 EXPECT_THAT(out, StrEq("one\n"));
647}
648
Felipe Lemefd8affa2016-09-30 17:38:57 -0700649TEST_F(DumpstateTest, RunCommandWithMultipleArgs) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700650 EXPECT_EQ(0, RunCommand("", {kEchoCommand, "one", "is", "the", "loniest", "number"}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700651 EXPECT_THAT(err, IsEmpty());
652 EXPECT_THAT(out, StrEq("one is the loniest number\n"));
653}
654
655TEST_F(DumpstateTest, RunCommandDryRun) {
656 SetDryRun(true);
Felipe Leme7447d7c2016-11-03 18:12:22 -0700657 EXPECT_EQ(0, RunCommand("I AM GROOT", {kSimpleCommand}));
Greg Kaiser3a811c12019-05-21 12:48:59 -0700658 // The duration may not get output, depending on how long it takes,
659 // so we just check the prefix.
Felipe Leme7447d7c2016-11-03 18:12:22 -0700660 EXPECT_THAT(out, StartsWith("------ I AM GROOT (" + kSimpleCommand +
Nandana Dutt47527b52019-03-29 15:34:36 +0000661 ") ------\n\t(skipped on dry run)\n"));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700662 EXPECT_THAT(err, IsEmpty());
663}
664
665TEST_F(DumpstateTest, RunCommandDryRunNoTitle) {
666 SetDryRun(true);
Felipe Leme7447d7c2016-11-03 18:12:22 -0700667 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700668 EXPECT_THAT(out, IsEmpty());
669 EXPECT_THAT(err, IsEmpty());
670}
671
672TEST_F(DumpstateTest, RunCommandDryRunAlways) {
673 SetDryRun(true);
Felipe Leme7447d7c2016-11-03 18:12:22 -0700674 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(10).Always().Build()));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700675 EXPECT_THAT(out, StrEq("stdout\n"));
676 EXPECT_THAT(err, StrEq("stderr\n"));
677}
678
Felipe Lemefd8affa2016-09-30 17:38:57 -0700679TEST_F(DumpstateTest, RunCommandNotFound) {
680 EXPECT_NE(0, RunCommand("", {"/there/cannot/be/such/command"}));
681 EXPECT_THAT(out, StartsWith("*** command '/there/cannot/be/such/command' failed: exit code"));
682 EXPECT_THAT(err, StartsWith("execvp on command '/there/cannot/be/such/command' failed"));
683}
684
685TEST_F(DumpstateTest, RunCommandFails) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700686 EXPECT_EQ(42, RunCommand("", {kSimpleCommand, "--exit", "42"}));
687 EXPECT_THAT(out, StrEq("stdout\n*** command '" + kSimpleCommand +
Felipe Leme9a523ae2016-10-20 15:10:33 -0700688 " --exit 42' failed: exit code 42\n"));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700689 EXPECT_THAT(err, StrEq("stderr\n*** command '" + kSimpleCommand +
Felipe Leme9a523ae2016-10-20 15:10:33 -0700690 " --exit 42' failed: exit code 42\n"));
Felipe Lemefd8affa2016-09-30 17:38:57 -0700691}
692
693TEST_F(DumpstateTest, RunCommandCrashes) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700694 EXPECT_NE(0, RunCommand("", {kSimpleCommand, "--crash"}));
Felipe Lemefd8affa2016-09-30 17:38:57 -0700695 // We don't know the exit code, so check just the prefix.
696 EXPECT_THAT(
Felipe Leme7447d7c2016-11-03 18:12:22 -0700697 out, StartsWith("stdout\n*** command '" + kSimpleCommand + " --crash' failed: exit code"));
Felipe Lemefd8affa2016-09-30 17:38:57 -0700698 EXPECT_THAT(
Felipe Leme7447d7c2016-11-03 18:12:22 -0700699 err, StartsWith("stderr\n*** command '" + kSimpleCommand + " --crash' failed: exit code"));
Felipe Lemefd8affa2016-09-30 17:38:57 -0700700}
701
702TEST_F(DumpstateTest, RunCommandTimesout) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700703 EXPECT_EQ(-1, RunCommand("", {kSimpleCommand, "--sleep", "2"},
Felipe Lemefd8affa2016-09-30 17:38:57 -0700704 CommandOptions::WithTimeout(1).Build()));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700705 EXPECT_THAT(out, StartsWith("stdout line1\n*** command '" + kSimpleCommand +
Felipe Lemefd8affa2016-09-30 17:38:57 -0700706 " --sleep 2' timed out after 1"));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700707 EXPECT_THAT(err, StartsWith("sleeping for 2s\n*** command '" + kSimpleCommand +
Felipe Lemefd8affa2016-09-30 17:38:57 -0700708 " --sleep 2' timed out after 1"));
709}
710
711TEST_F(DumpstateTest, RunCommandIsKilled) {
712 CaptureStdout();
713 CaptureStderr();
714
715 std::thread t([=]() {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700716 EXPECT_EQ(SIGTERM, ds.RunCommand("", {kSimpleCommand, "--pid", "--sleep", "20"},
Felipe Lemefd8affa2016-09-30 17:38:57 -0700717 CommandOptions::WithTimeout(100).Always().Build()));
718 });
719
720 // Capture pid and pre-sleep output.
721 sleep(1); // Wait a little bit to make sure pid and 1st line were printed.
722 std::string err = GetCapturedStderr();
723 EXPECT_THAT(err, StrEq("sleeping for 20s\n"));
724
725 std::string out = GetCapturedStdout();
726 std::vector<std::string> lines = android::base::Split(out, "\n");
727 ASSERT_EQ(3, (int)lines.size()) << "Invalid lines before sleep: " << out;
728
729 int pid = atoi(lines[0].c_str());
730 EXPECT_THAT(lines[1], StrEq("stdout line1"));
731 EXPECT_THAT(lines[2], IsEmpty()); // \n
732
733 // Then kill the process.
734 CaptureStdout();
735 CaptureStderr();
736 ASSERT_EQ(0, kill(pid, SIGTERM)) << "failed to kill pid " << pid;
737 t.join();
738
739 // Finally, check output after murder.
740 out = GetCapturedStdout();
741 err = GetCapturedStderr();
742
Felipe Leme7447d7c2016-11-03 18:12:22 -0700743 EXPECT_THAT(out, StrEq("*** command '" + kSimpleCommand +
Felipe Lemefd8affa2016-09-30 17:38:57 -0700744 " --pid --sleep 20' failed: killed by signal 15\n"));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700745 EXPECT_THAT(err, StrEq("*** command '" + kSimpleCommand +
Felipe Lemefd8affa2016-09-30 17:38:57 -0700746 " --pid --sleep 20' failed: killed by signal 15\n"));
747}
748
Felipe Leme75876a22016-10-27 16:31:27 -0700749TEST_F(DumpstateTest, RunCommandProgress) {
750 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
751 ds.listener_ = listener;
Felipe Leme7447d7c2016-11-03 18:12:22 -0700752 SetProgress(0, 30);
Felipe Leme75876a22016-10-27 16:31:27 -0700753
Nandana Duttbabf6c72019-01-15 14:11:12 +0000754 EXPECT_CALL(*listener, onProgress(66)); // 20/30 %
Felipe Leme7447d7c2016-11-03 18:12:22 -0700755 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(20).Build()));
Abhijeet Kaured5d6a62019-10-07 15:02:05 +0100756 std::string progress_message = GetProgressMessage(20, 30);
Felipe Leme75876a22016-10-27 16:31:27 -0700757 EXPECT_THAT(out, StrEq("stdout\n"));
758 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
759
Nandana Dutt402a8392019-06-14 14:25:13 +0100760 EXPECT_CALL(*listener, onProgress(80)); // 24/30 %
761 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(4).Build()));
Abhijeet Kaured5d6a62019-10-07 15:02:05 +0100762 progress_message = GetProgressMessage(24, 30);
Felipe Leme75876a22016-10-27 16:31:27 -0700763 EXPECT_THAT(out, StrEq("stdout\n"));
764 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
765
766 // Make sure command ran while in dry_run is counted.
767 SetDryRun(true);
Nandana Dutt402a8392019-06-14 14:25:13 +0100768 EXPECT_CALL(*listener, onProgress(90)); // 27/30 %
769 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(3).Build()));
Abhijeet Kaured5d6a62019-10-07 15:02:05 +0100770 progress_message = GetProgressMessage(27, 30);
Felipe Leme75876a22016-10-27 16:31:27 -0700771 EXPECT_THAT(out, IsEmpty());
772 EXPECT_THAT(err, StrEq(progress_message));
773
Nandana Dutt402a8392019-06-14 14:25:13 +0100774 SetDryRun(false);
775 EXPECT_CALL(*listener, onProgress(96)); // 29/30 %
776 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(2).Build()));
Abhijeet Kaured5d6a62019-10-07 15:02:05 +0100777 progress_message = GetProgressMessage(29, 30);
Felipe Leme009ecbb2016-11-07 10:18:44 -0800778 EXPECT_THAT(out, StrEq("stdout\n"));
779 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
780
Nandana Dutt402a8392019-06-14 14:25:13 +0100781 EXPECT_CALL(*listener, onProgress(100)); // 30/30 %
Felipe Leme009ecbb2016-11-07 10:18:44 -0800782 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).Build()));
Abhijeet Kaured5d6a62019-10-07 15:02:05 +0100783 progress_message = GetProgressMessage(30, 30);
Felipe Leme009ecbb2016-11-07 10:18:44 -0800784 EXPECT_THAT(out, StrEq("stdout\n"));
785 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
786
787 ds.listener_.clear();
788}
789
Felipe Lemed80e6b62016-10-03 13:08:14 -0700790TEST_F(DumpstateTest, RunCommandDropRoot) {
Felipe Leme46b85da2016-11-21 17:40:45 -0800791 if (!IsStandalone()) {
792 // TODO: temporarily disabled because it might cause other tests to fail after dropping
793 // to Shell - need to refactor tests to avoid this problem)
794 MYLOGE("Skipping DumpstateTest.RunCommandDropRoot() on test suite\n")
795 return;
796 }
Felipe Lemed80e6b62016-10-03 13:08:14 -0700797 // First check root case - only available when running with 'adb root'.
798 uid_t uid = getuid();
799 if (uid == 0) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700800 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"}));
Felipe Lemed80e6b62016-10-03 13:08:14 -0700801 EXPECT_THAT(out, StrEq("0\nstdout\n"));
802 EXPECT_THAT(err, StrEq("stderr\n"));
803 return;
804 }
Felipe Leme7447d7c2016-11-03 18:12:22 -0700805 // Then run dropping root.
806 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
Felipe Lemed80e6b62016-10-03 13:08:14 -0700807 CommandOptions::WithTimeout(1).DropRoot().Build()));
808 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
Felipe Leme26c41572016-10-06 14:34:43 -0700809 EXPECT_THAT(err, StrEq("drop_root_user(): already running as Shell\nstderr\n"));
Felipe Lemed80e6b62016-10-03 13:08:14 -0700810}
811
812TEST_F(DumpstateTest, RunCommandAsRootUserBuild) {
Felipe Leme46b85da2016-11-21 17:40:45 -0800813 if (!IsStandalone()) {
814 // TODO: temporarily disabled because it might cause other tests to fail after dropping
815 // to Shell - need to refactor tests to avoid this problem)
816 MYLOGE("Skipping DumpstateTest.RunCommandAsRootUserBuild() on test suite\n")
817 return;
818 }
Felipe Lemef0292972016-11-22 13:57:05 -0800819 if (!PropertiesHelper::IsUserBuild()) {
Felipe Lemed80e6b62016-10-03 13:08:14 -0700820 // Emulates user build if necessarily.
821 SetBuildType("user");
822 }
823
824 DropRoot();
825
Felipe Leme7447d7c2016-11-03 18:12:22 -0700826 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).AsRoot().Build()));
Felipe Lemed80e6b62016-10-03 13:08:14 -0700827
828 // We don't know the exact path of su, so we just check for the 'root ...' commands
829 EXPECT_THAT(out, StartsWith("Skipping"));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700830 EXPECT_THAT(out, EndsWith("root " + kSimpleCommand + "' on user build.\n"));
Felipe Lemed80e6b62016-10-03 13:08:14 -0700831 EXPECT_THAT(err, IsEmpty());
832}
833
Felipe Leme46b85da2016-11-21 17:40:45 -0800834TEST_F(DumpstateTest, RunCommandAsRootNonUserBuild) {
835 if (!IsStandalone()) {
836 // TODO: temporarily disabled because it might cause other tests to fail after dropping
837 // to Shell - need to refactor tests to avoid this problem)
838 MYLOGE("Skipping DumpstateTest.RunCommandAsRootNonUserBuild() on test suite\n")
839 return;
840 }
Felipe Lemef0292972016-11-22 13:57:05 -0800841 if (PropertiesHelper::IsUserBuild()) {
Felipe Leme46b85da2016-11-21 17:40:45 -0800842 ALOGI("Skipping RunCommandAsRootNonUserBuild on user builds\n");
843 return;
844 }
845
846 DropRoot();
847
848 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
849 CommandOptions::WithTimeout(1).AsRoot().Build()));
850
851 EXPECT_THAT(out, StrEq("0\nstdout\n"));
852 EXPECT_THAT(err, StrEq("stderr\n"));
853}
854
Nandana Dutt4b392be2018-11-02 16:17:05 +0000855TEST_F(DumpstateTest, RunCommandAsRootNonUserBuild_withUnroot) {
856 if (!IsStandalone()) {
857 // TODO: temporarily disabled because it might cause other tests to fail after dropping
858 // to Shell - need to refactor tests to avoid this problem)
859 MYLOGE(
860 "Skipping DumpstateTest.RunCommandAsRootNonUserBuild_withUnroot() "
861 "on test suite\n")
862 return;
863 }
864 if (PropertiesHelper::IsUserBuild()) {
865 ALOGI("Skipping RunCommandAsRootNonUserBuild_withUnroot on user builds\n");
866 return;
867 }
868
869 // Same test as above, but with unroot property set, which will override su availability.
870 SetUnroot(true);
871 DropRoot();
872
873 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
874 CommandOptions::WithTimeout(1).AsRoot().Build()));
875
876 // AsRoot is ineffective.
877 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
878 EXPECT_THAT(err, StrEq("drop_root_user(): already running as Shell\nstderr\n"));
879}
880
Yifan Hong48e83a12017-10-03 14:10:07 -0700881TEST_F(DumpstateTest, RunCommandAsRootIfAvailableOnUserBuild) {
882 if (!IsStandalone()) {
883 // TODO: temporarily disabled because it might cause other tests to fail after dropping
884 // to Shell - need to refactor tests to avoid this problem)
885 MYLOGE("Skipping DumpstateTest.RunCommandAsRootIfAvailableOnUserBuild() on test suite\n")
886 return;
887 }
888 if (!PropertiesHelper::IsUserBuild()) {
889 // Emulates user build if necessarily.
890 SetBuildType("user");
891 }
892
893 DropRoot();
894
895 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
896 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
897
898 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
899 EXPECT_THAT(err, StrEq("stderr\n"));
900}
901
902TEST_F(DumpstateTest, RunCommandAsRootIfAvailableOnDebugBuild) {
903 if (!IsStandalone()) {
904 // TODO: temporarily disabled because it might cause other tests to fail after dropping
905 // to Shell - need to refactor tests to avoid this problem)
906 MYLOGE("Skipping DumpstateTest.RunCommandAsRootIfAvailableOnDebugBuild() on test suite\n")
907 return;
908 }
909 if (PropertiesHelper::IsUserBuild()) {
910 ALOGI("Skipping RunCommandAsRootNonUserBuild on user builds\n");
911 return;
912 }
913
914 DropRoot();
915
916 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
917 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
918
919 EXPECT_THAT(out, StrEq("0\nstdout\n"));
920 EXPECT_THAT(err, StrEq("stderr\n"));
921}
922
Nandana Dutt4b392be2018-11-02 16:17:05 +0000923TEST_F(DumpstateTest, RunCommandAsRootIfAvailableOnDebugBuild_withUnroot) {
924 if (!IsStandalone()) {
925 // TODO: temporarily disabled because it might cause other tests to fail after dropping
926 // to Shell - need to refactor tests to avoid this problem)
927 MYLOGE(
928 "Skipping DumpstateTest.RunCommandAsRootIfAvailableOnDebugBuild_withUnroot() "
929 "on test suite\n")
930 return;
931 }
932 if (PropertiesHelper::IsUserBuild()) {
933 ALOGI("Skipping RunCommandAsRootIfAvailableOnDebugBuild_withUnroot on user builds\n");
934 return;
935 }
936 // Same test as above, but with unroot property set, which will override su availability.
937 SetUnroot(true);
938
939 DropRoot();
940
941 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
942 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
943
944 // It's a userdebug build, so "su root" should be available, but unroot=true overrides it.
945 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
946 EXPECT_THAT(err, StrEq("stderr\n"));
947}
948
Felipe Lemecef02982016-10-03 17:22:22 -0700949TEST_F(DumpstateTest, DumpFileNotFoundNoTitle) {
950 EXPECT_EQ(-1, DumpFile("", "/I/cant/believe/I/exist"));
951 EXPECT_THAT(out,
952 StrEq("*** Error dumping /I/cant/believe/I/exist: No such file or directory\n"));
953 EXPECT_THAT(err, IsEmpty());
954}
955
956TEST_F(DumpstateTest, DumpFileNotFoundWithTitle) {
957 EXPECT_EQ(-1, DumpFile("Y U NO EXIST?", "/I/cant/believe/I/exist"));
958 EXPECT_THAT(err, IsEmpty());
Greg Kaiser3a811c12019-05-21 12:48:59 -0700959 // The duration may not get output, depending on how long it takes,
960 // so we just check the prefix.
Felipe Lemecef02982016-10-03 17:22:22 -0700961 EXPECT_THAT(out, StartsWith("*** Error dumping /I/cant/believe/I/exist (Y U NO EXIST?): No "
962 "such file or directory\n"));
Felipe Lemecef02982016-10-03 17:22:22 -0700963}
964
965TEST_F(DumpstateTest, DumpFileSingleLine) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700966 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -0700967 EXPECT_THAT(err, IsEmpty());
968 EXPECT_THAT(out, StrEq("I AM LINE1\n")); // dumpstate adds missing newline
969}
970
971TEST_F(DumpstateTest, DumpFileSingleLineWithNewLine) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700972 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line-with-newline.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -0700973 EXPECT_THAT(err, IsEmpty());
974 EXPECT_THAT(out, StrEq("I AM LINE1\n"));
975}
976
977TEST_F(DumpstateTest, DumpFileMultipleLines) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700978 EXPECT_EQ(0, DumpFile("", kTestDataPath + "multiple-lines.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -0700979 EXPECT_THAT(err, IsEmpty());
980 EXPECT_THAT(out, StrEq("I AM LINE1\nI AM LINE2\nI AM LINE3\n"));
981}
982
983TEST_F(DumpstateTest, DumpFileMultipleLinesWithNewLine) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700984 EXPECT_EQ(0, DumpFile("", kTestDataPath + "multiple-lines-with-newline.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -0700985 EXPECT_THAT(err, IsEmpty());
986 EXPECT_THAT(out, StrEq("I AM LINE1\nI AM LINE2\nI AM LINE3\n"));
987}
988
989TEST_F(DumpstateTest, DumpFileOnDryRunNoTitle) {
990 SetDryRun(true);
Felipe Leme7447d7c2016-11-03 18:12:22 -0700991 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -0700992 EXPECT_THAT(err, IsEmpty());
993 EXPECT_THAT(out, IsEmpty());
994}
995
996TEST_F(DumpstateTest, DumpFileOnDryRun) {
997 SetDryRun(true);
Felipe Leme7447d7c2016-11-03 18:12:22 -0700998 EXPECT_EQ(0, DumpFile("Might as well dump. Dump!", kTestDataPath + "single-line.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -0700999 EXPECT_THAT(err, IsEmpty());
Felipe Leme46b85da2016-11-21 17:40:45 -08001000 EXPECT_THAT(
1001 out, StartsWith("------ Might as well dump. Dump! (" + kTestDataPath + "single-line.txt:"));
Nandana Dutt47527b52019-03-29 15:34:36 +00001002 EXPECT_THAT(out, HasSubstr("\n\t(skipped on dry run)\n"));
Felipe Lemecef02982016-10-03 17:22:22 -07001003}
1004
Felipe Leme75876a22016-10-27 16:31:27 -07001005TEST_F(DumpstateTest, DumpFileUpdateProgress) {
1006 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
1007 ds.listener_ = listener;
Felipe Leme7447d7c2016-11-03 18:12:22 -07001008 SetProgress(0, 30);
Felipe Leme75876a22016-10-27 16:31:27 -07001009
Nandana Duttbabf6c72019-01-15 14:11:12 +00001010 EXPECT_CALL(*listener, onProgress(16)); // 5/30 %
Felipe Leme7447d7c2016-11-03 18:12:22 -07001011 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
Felipe Leme75876a22016-10-27 16:31:27 -07001012
Abhijeet Kaured5d6a62019-10-07 15:02:05 +01001013 std::string progress_message = GetProgressMessage(5, 30); // TODO: unhardcode WEIGHT_FILE (5)?
Felipe Leme75876a22016-10-27 16:31:27 -07001014 EXPECT_THAT(err, StrEq(progress_message));
1015 EXPECT_THAT(out, StrEq("I AM LINE1\n")); // dumpstate adds missing newline
1016
1017 ds.listener_.clear();
1018}
1019
Rhed Jao1c855122020-07-16 17:37:39 +08001020TEST_F(DumpstateTest, DumpPool_withOutputToFileAndParallelRunEnabled_notNull) {
1021 ds.options_->use_socket = false;
1022 SetParallelRun(true);
1023 EnableParallelRunIfNeeded();
1024 EXPECT_TRUE(ds.options_->OutputToFile());
Rhed Jao4875aa62020-07-20 17:46:29 +08001025 EXPECT_TRUE(ds.zip_entry_tasks_);
Rhed Jao1c855122020-07-16 17:37:39 +08001026 EXPECT_TRUE(ds.dump_pool_);
1027}
1028
1029TEST_F(DumpstateTest, DumpPool_withNotOutputToFile_isNull) {
1030 ds.options_->use_socket = true;
1031 EnableParallelRunIfNeeded();
1032 EXPECT_FALSE(ds.options_->OutputToFile());
Rhed Jao4875aa62020-07-20 17:46:29 +08001033 EXPECT_FALSE(ds.zip_entry_tasks_);
Rhed Jao1c855122020-07-16 17:37:39 +08001034 EXPECT_FALSE(ds.dump_pool_);
1035}
1036
1037TEST_F(DumpstateTest, DumpPool_withParallelRunDisabled_isNull) {
1038 SetParallelRun(false);
1039 EnableParallelRunIfNeeded();
Rhed Jao4875aa62020-07-20 17:46:29 +08001040 EXPECT_FALSE(ds.zip_entry_tasks_);
Rhed Jao1c855122020-07-16 17:37:39 +08001041 EXPECT_FALSE(ds.dump_pool_);
1042}
1043
Felipe Leme7447d7c2016-11-03 18:12:22 -07001044class DumpstateServiceTest : public DumpstateBaseTest {
Felipe Leme75876a22016-10-27 16:31:27 -07001045 public:
1046 DumpstateService dss;
1047};
1048
Felipe Leme7447d7c2016-11-03 18:12:22 -07001049class ProgressTest : public DumpstateBaseTest {
1050 public:
1051 Progress GetInstance(int32_t max, double growth_factor, const std::string& path = "") {
1052 return Progress(max, growth_factor, path);
1053 }
1054
1055 void AssertStats(const std::string& path, int32_t expected_runs, int32_t expected_average) {
1056 std::string expected_content =
1057 android::base::StringPrintf("%d %d\n", expected_runs, expected_average);
1058 std::string actual_content;
Felipe Leme46b85da2016-11-21 17:40:45 -08001059 ReadFileToString(path, &actual_content);
Felipe Leme7447d7c2016-11-03 18:12:22 -07001060 ASSERT_THAT(actual_content, StrEq(expected_content)) << "invalid stats on " << path;
1061 }
1062};
1063
1064TEST_F(ProgressTest, SimpleTest) {
1065 Progress progress;
1066 EXPECT_EQ(0, progress.Get());
1067 EXPECT_EQ(Progress::kDefaultMax, progress.GetInitialMax());
1068 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1069
1070 bool max_increased = progress.Inc(1);
1071 EXPECT_EQ(1, progress.Get());
1072 EXPECT_EQ(Progress::kDefaultMax, progress.GetInitialMax());
1073 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1074 EXPECT_FALSE(max_increased);
1075
1076 // Ignore negative increase.
1077 max_increased = progress.Inc(-1);
1078 EXPECT_EQ(1, progress.Get());
1079 EXPECT_EQ(Progress::kDefaultMax, progress.GetInitialMax());
1080 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1081 EXPECT_FALSE(max_increased);
1082}
1083
1084TEST_F(ProgressTest, MaxGrowsInsideNewRange) {
1085 Progress progress = GetInstance(10, 1.2); // 20% growth factor
1086 EXPECT_EQ(0, progress.Get());
1087 EXPECT_EQ(10, progress.GetInitialMax());
1088 EXPECT_EQ(10, progress.GetMax());
1089
1090 // No increase
1091 bool max_increased = progress.Inc(10);
1092 EXPECT_EQ(10, progress.Get());
1093 EXPECT_EQ(10, progress.GetMax());
1094 EXPECT_FALSE(max_increased);
1095
1096 // Increase, with new value < max*20%
1097 max_increased = progress.Inc(1);
1098 EXPECT_EQ(11, progress.Get());
1099 EXPECT_EQ(13, progress.GetMax()); // 11 average * 20% growth = 13.2 = 13
1100 EXPECT_TRUE(max_increased);
1101}
1102
1103TEST_F(ProgressTest, MaxGrowsOutsideNewRange) {
1104 Progress progress = GetInstance(10, 1.2); // 20% growth factor
1105 EXPECT_EQ(0, progress.Get());
1106 EXPECT_EQ(10, progress.GetInitialMax());
1107 EXPECT_EQ(10, progress.GetMax());
1108
1109 // No increase
1110 bool max_increased = progress.Inc(10);
1111 EXPECT_EQ(10, progress.Get());
1112 EXPECT_EQ(10, progress.GetMax());
1113 EXPECT_FALSE(max_increased);
1114
1115 // Increase, with new value > max*20%
1116 max_increased = progress.Inc(5);
1117 EXPECT_EQ(15, progress.Get());
1118 EXPECT_EQ(18, progress.GetMax()); // 15 average * 20% growth = 18
1119 EXPECT_TRUE(max_increased);
1120}
1121
1122TEST_F(ProgressTest, InvalidPath) {
1123 Progress progress("/devil/null");
1124 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1125}
1126
1127TEST_F(ProgressTest, EmptyFile) {
1128 Progress progress(CopyTextFileFixture("empty-file.txt"));
1129 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1130}
1131
1132TEST_F(ProgressTest, InvalidLine1stEntryNAN) {
1133 Progress progress(CopyTextFileFixture("stats-invalid-1st-NAN.txt"));
1134 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1135}
1136
1137TEST_F(ProgressTest, InvalidLine2ndEntryNAN) {
1138 Progress progress(CopyTextFileFixture("stats-invalid-2nd-NAN.txt"));
1139 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1140}
1141
1142TEST_F(ProgressTest, InvalidLineBothNAN) {
1143 Progress progress(CopyTextFileFixture("stats-invalid-both-NAN.txt"));
1144 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1145}
1146
1147TEST_F(ProgressTest, InvalidLine1stEntryNegative) {
1148 Progress progress(CopyTextFileFixture("stats-invalid-1st-negative.txt"));
1149 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1150}
1151
1152TEST_F(ProgressTest, InvalidLine2ndEntryNegative) {
1153 Progress progress(CopyTextFileFixture("stats-invalid-2nd-negative.txt"));
1154 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1155}
1156
1157TEST_F(ProgressTest, InvalidLine1stEntryTooBig) {
1158 Progress progress(CopyTextFileFixture("stats-invalid-1st-too-big.txt"));
1159 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1160}
1161
1162TEST_F(ProgressTest, InvalidLine2ndEntryTooBig) {
1163 Progress progress(CopyTextFileFixture("stats-invalid-2nd-too-big.txt"));
1164 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1165}
1166
1167// Tests stats are properly saved when the file does not exists.
1168TEST_F(ProgressTest, FirstTime) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001169 if (!IsStandalone()) {
1170 // TODO: temporarily disabled because it's failing when running as suite
1171 MYLOGE("Skipping ProgressTest.FirstTime() on test suite\n")
1172 return;
1173 }
1174
Felipe Leme7447d7c2016-11-03 18:12:22 -07001175 std::string path = kTestDataPath + "FirstTime.txt";
1176 android::base::RemoveFileIfExists(path);
1177
1178 Progress run1(path);
1179 EXPECT_EQ(0, run1.Get());
1180 EXPECT_EQ(Progress::kDefaultMax, run1.GetInitialMax());
1181 EXPECT_EQ(Progress::kDefaultMax, run1.GetMax());
1182
1183 bool max_increased = run1.Inc(20);
1184 EXPECT_EQ(20, run1.Get());
1185 EXPECT_EQ(Progress::kDefaultMax, run1.GetMax());
1186 EXPECT_FALSE(max_increased);
1187
1188 run1.Save();
1189 AssertStats(path, 1, 20);
1190}
1191
1192// Tests what happens when the persistent settings contains the average duration of 1 run.
1193// Data on file is 1 run and 109 average.
1194TEST_F(ProgressTest, SecondTime) {
1195 std::string path = CopyTextFileFixture("stats-one-run-no-newline.txt");
1196
1197 Progress run1 = GetInstance(-42, 1.2, path);
1198 EXPECT_EQ(0, run1.Get());
1199 EXPECT_EQ(10, run1.GetInitialMax());
1200 EXPECT_EQ(10, run1.GetMax());
1201
1202 bool max_increased = run1.Inc(20);
1203 EXPECT_EQ(20, run1.Get());
1204 EXPECT_EQ(24, run1.GetMax());
1205 EXPECT_TRUE(max_increased);
1206
1207 // Average now is 2 runs and (10 + 20)/ 2 = 15
1208 run1.Save();
1209 AssertStats(path, 2, 15);
1210
1211 Progress run2 = GetInstance(-42, 1.2, path);
1212 EXPECT_EQ(0, run2.Get());
1213 EXPECT_EQ(15, run2.GetInitialMax());
1214 EXPECT_EQ(15, run2.GetMax());
1215
1216 max_increased = run2.Inc(25);
1217 EXPECT_EQ(25, run2.Get());
1218 EXPECT_EQ(30, run2.GetMax());
1219 EXPECT_TRUE(max_increased);
1220
1221 // Average now is 3 runs and (15 * 2 + 25)/ 3 = 18.33 = 18
1222 run2.Save();
1223 AssertStats(path, 3, 18);
1224
1225 Progress run3 = GetInstance(-42, 1.2, path);
1226 EXPECT_EQ(0, run3.Get());
1227 EXPECT_EQ(18, run3.GetInitialMax());
1228 EXPECT_EQ(18, run3.GetMax());
1229
1230 // Make sure average decreases as well
1231 max_increased = run3.Inc(5);
1232 EXPECT_EQ(5, run3.Get());
1233 EXPECT_EQ(18, run3.GetMax());
1234 EXPECT_FALSE(max_increased);
1235
1236 // Average now is 4 runs and (18 * 3 + 5)/ 4 = 14.75 = 14
1237 run3.Save();
1238 AssertStats(path, 4, 14);
1239}
1240
1241// Tests what happens when the persistent settings contains the average duration of 2 runs.
1242// Data on file is 2 runs and 15 average.
1243TEST_F(ProgressTest, ThirdTime) {
1244 std::string path = CopyTextFileFixture("stats-two-runs.txt");
1245 AssertStats(path, 2, 15); // Sanity check
1246
1247 Progress run1 = GetInstance(-42, 1.2, path);
1248 EXPECT_EQ(0, run1.Get());
1249 EXPECT_EQ(15, run1.GetInitialMax());
1250 EXPECT_EQ(15, run1.GetMax());
1251
1252 bool max_increased = run1.Inc(20);
1253 EXPECT_EQ(20, run1.Get());
1254 EXPECT_EQ(24, run1.GetMax());
1255 EXPECT_TRUE(max_increased);
1256
1257 // Average now is 3 runs and (15 * 2 + 20)/ 3 = 16.66 = 16
1258 run1.Save();
1259 AssertStats(path, 3, 16);
1260}
1261
Felipe Leme46b85da2016-11-21 17:40:45 -08001262class DumpstateUtilTest : public DumpstateBaseTest {
1263 public:
1264 void SetUp() {
1265 DumpstateBaseTest::SetUp();
1266 SetDryRun(false);
1267 }
1268
Felipe Leme46b85da2016-11-21 17:40:45 -08001269 void CaptureFdOut() {
Felipe Lemef0292972016-11-22 13:57:05 -08001270 ReadFileToString(path_, &out);
Felipe Leme46b85da2016-11-21 17:40:45 -08001271 }
1272
1273 void CreateFd(const std::string& name) {
1274 path_ = kTestDataPath + name;
1275 MYLOGD("Creating fd for file %s\n", path_.c_str());
1276
1277 fd = TEMP_FAILURE_RETRY(open(path_.c_str(),
1278 O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW,
1279 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH));
1280 ASSERT_GE(fd, 0) << "could not create FD for path " << path_;
1281 }
1282
1283 // Runs a command into the `fd` and capture `stderr`.
Felipe Lemef0292972016-11-22 13:57:05 -08001284 int RunCommand(const std::string& title, const std::vector<std::string>& full_command,
Felipe Leme46b85da2016-11-21 17:40:45 -08001285 const CommandOptions& options = CommandOptions::DEFAULT) {
1286 CaptureStderr();
Felipe Lemef0292972016-11-22 13:57:05 -08001287 int status = RunCommandToFd(fd, title, full_command, options);
Felipe Leme46b85da2016-11-21 17:40:45 -08001288 close(fd);
1289
1290 CaptureFdOut();
1291 err = GetCapturedStderr();
1292 return status;
1293 }
1294
1295 // Dumps a file and into the `fd` and `stderr`.
Felipe Lemef0292972016-11-22 13:57:05 -08001296 int DumpFile(const std::string& title, const std::string& path) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001297 CaptureStderr();
Felipe Lemef0292972016-11-22 13:57:05 -08001298 int status = DumpFileToFd(fd, title, path);
Felipe Leme46b85da2016-11-21 17:40:45 -08001299 close(fd);
1300
1301 CaptureFdOut();
1302 err = GetCapturedStderr();
1303 return status;
1304 }
1305
1306 int fd;
1307
1308 // 'fd` output and `stderr` from the last command ran.
1309 std::string out, err;
1310
1311 private:
1312 std::string path_;
1313};
1314
1315TEST_F(DumpstateUtilTest, RunCommandNoArgs) {
Felipe Lemef0292972016-11-22 13:57:05 -08001316 CreateFd("RunCommandNoArgs.txt");
1317 EXPECT_EQ(-1, RunCommand("", {}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001318}
1319
Felipe Lemef0292972016-11-22 13:57:05 -08001320TEST_F(DumpstateUtilTest, RunCommandNoTitle) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001321 CreateFd("RunCommandWithNoArgs.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001322 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001323 EXPECT_THAT(out, StrEq("stdout\n"));
1324 EXPECT_THAT(err, StrEq("stderr\n"));
1325}
1326
Felipe Lemef0292972016-11-22 13:57:05 -08001327TEST_F(DumpstateUtilTest, RunCommandWithTitle) {
1328 CreateFd("RunCommandWithNoArgs.txt");
1329 EXPECT_EQ(0, RunCommand("I AM GROOT", {kSimpleCommand}));
1330 EXPECT_THAT(out, StrEq("------ I AM GROOT (" + kSimpleCommand + ") ------\nstdout\n"));
1331 EXPECT_THAT(err, StrEq("stderr\n"));
1332}
1333
Felipe Leme46b85da2016-11-21 17:40:45 -08001334TEST_F(DumpstateUtilTest, RunCommandWithOneArg) {
1335 CreateFd("RunCommandWithOneArg.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001336 EXPECT_EQ(0, RunCommand("", {kEchoCommand, "one"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001337 EXPECT_THAT(err, IsEmpty());
1338 EXPECT_THAT(out, StrEq("one\n"));
1339}
1340
1341TEST_F(DumpstateUtilTest, RunCommandWithMultipleArgs) {
1342 CreateFd("RunCommandWithMultipleArgs.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001343 EXPECT_EQ(0, RunCommand("", {kEchoCommand, "one", "is", "the", "loniest", "number"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001344 EXPECT_THAT(err, IsEmpty());
1345 EXPECT_THAT(out, StrEq("one is the loniest number\n"));
1346}
1347
1348TEST_F(DumpstateUtilTest, RunCommandWithLoggingMessage) {
1349 CreateFd("RunCommandWithLoggingMessage.txt");
1350 EXPECT_EQ(
Felipe Lemef0292972016-11-22 13:57:05 -08001351 0, RunCommand("", {kSimpleCommand},
Felipe Leme46b85da2016-11-21 17:40:45 -08001352 CommandOptions::WithTimeout(10).Log("COMMAND, Y U NO LOG FIRST?").Build()));
1353 EXPECT_THAT(out, StrEq("stdout\n"));
1354 EXPECT_THAT(err, StrEq("COMMAND, Y U NO LOG FIRST?stderr\n"));
1355}
1356
1357TEST_F(DumpstateUtilTest, RunCommandRedirectStderr) {
1358 CreateFd("RunCommandRedirectStderr.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001359 EXPECT_EQ(0, RunCommand("", {kSimpleCommand},
1360 CommandOptions::WithTimeout(10).RedirectStderr().Build()));
Felipe Leme46b85da2016-11-21 17:40:45 -08001361 EXPECT_THAT(out, IsEmpty());
1362 EXPECT_THAT(err, StrEq("stdout\nstderr\n"));
1363}
1364
1365TEST_F(DumpstateUtilTest, RunCommandDryRun) {
1366 CreateFd("RunCommandDryRun.txt");
1367 SetDryRun(true);
Felipe Lemef0292972016-11-22 13:57:05 -08001368 EXPECT_EQ(0, RunCommand("I AM GROOT", {kSimpleCommand}));
1369 EXPECT_THAT(out, StrEq(android::base::StringPrintf(
1370 "------ I AM GROOT (%s) ------\n\t(skipped on dry run)\n",
1371 kSimpleCommand.c_str())));
1372 EXPECT_THAT(err, IsEmpty());
1373}
1374
1375TEST_F(DumpstateUtilTest, RunCommandDryRunNoTitle) {
1376 CreateFd("RunCommandDryRun.txt");
1377 SetDryRun(true);
1378 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001379 EXPECT_THAT(
1380 out, StrEq(android::base::StringPrintf("%s: skipped on dry run\n", kSimpleCommand.c_str())));
1381 EXPECT_THAT(err, IsEmpty());
1382}
1383
1384TEST_F(DumpstateUtilTest, RunCommandDryRunAlways) {
1385 CreateFd("RunCommandDryRunAlways.txt");
1386 SetDryRun(true);
Felipe Lemef0292972016-11-22 13:57:05 -08001387 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(10).Always().Build()));
Felipe Leme46b85da2016-11-21 17:40:45 -08001388 EXPECT_THAT(out, StrEq("stdout\n"));
1389 EXPECT_THAT(err, StrEq("stderr\n"));
1390}
1391
1392TEST_F(DumpstateUtilTest, RunCommandNotFound) {
1393 CreateFd("RunCommandNotFound.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001394 EXPECT_NE(0, RunCommand("", {"/there/cannot/be/such/command"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001395 EXPECT_THAT(out, StartsWith("*** command '/there/cannot/be/such/command' failed: exit code"));
1396 EXPECT_THAT(err, StartsWith("execvp on command '/there/cannot/be/such/command' failed"));
1397}
1398
1399TEST_F(DumpstateUtilTest, RunCommandFails) {
1400 CreateFd("RunCommandFails.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001401 EXPECT_EQ(42, RunCommand("", {kSimpleCommand, "--exit", "42"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001402 EXPECT_THAT(out, StrEq("stdout\n*** command '" + kSimpleCommand +
1403 " --exit 42' failed: exit code 42\n"));
1404 EXPECT_THAT(err, StrEq("stderr\n*** command '" + kSimpleCommand +
1405 " --exit 42' failed: exit code 42\n"));
1406}
1407
1408TEST_F(DumpstateUtilTest, RunCommandCrashes) {
1409 CreateFd("RunCommandCrashes.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001410 EXPECT_NE(0, RunCommand("", {kSimpleCommand, "--crash"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001411 // We don't know the exit code, so check just the prefix.
1412 EXPECT_THAT(
1413 out, StartsWith("stdout\n*** command '" + kSimpleCommand + " --crash' failed: exit code"));
1414 EXPECT_THAT(
1415 err, StartsWith("stderr\n*** command '" + kSimpleCommand + " --crash' failed: exit code"));
1416}
1417
Vishnu Nair6921f802017-11-22 09:17:23 -08001418TEST_F(DumpstateUtilTest, RunCommandTimesoutWithSec) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001419 CreateFd("RunCommandTimesout.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001420 EXPECT_EQ(-1, RunCommand("", {kSimpleCommand, "--sleep", "2"},
1421 CommandOptions::WithTimeout(1).Build()));
Felipe Leme46b85da2016-11-21 17:40:45 -08001422 EXPECT_THAT(out, StartsWith("stdout line1\n*** command '" + kSimpleCommand +
1423 " --sleep 2' timed out after 1"));
1424 EXPECT_THAT(err, StartsWith("sleeping for 2s\n*** command '" + kSimpleCommand +
1425 " --sleep 2' timed out after 1"));
1426}
1427
Vishnu Nair6921f802017-11-22 09:17:23 -08001428TEST_F(DumpstateUtilTest, RunCommandTimesoutWithMsec) {
1429 CreateFd("RunCommandTimesout.txt");
1430 EXPECT_EQ(-1, RunCommand("", {kSimpleCommand, "--sleep", "2"},
1431 CommandOptions::WithTimeoutInMs(1000).Build()));
1432 EXPECT_THAT(out, StartsWith("stdout line1\n*** command '" + kSimpleCommand +
1433 " --sleep 2' timed out after 1"));
1434 EXPECT_THAT(err, StartsWith("sleeping for 2s\n*** command '" + kSimpleCommand +
1435 " --sleep 2' timed out after 1"));
1436}
1437
1438
Felipe Leme46b85da2016-11-21 17:40:45 -08001439TEST_F(DumpstateUtilTest, RunCommandIsKilled) {
1440 CreateFd("RunCommandIsKilled.txt");
1441 CaptureStderr();
1442
1443 std::thread t([=]() {
Felipe Lemef0292972016-11-22 13:57:05 -08001444 EXPECT_EQ(SIGTERM, RunCommandToFd(fd, "", {kSimpleCommand, "--pid", "--sleep", "20"},
Felipe Leme46b85da2016-11-21 17:40:45 -08001445 CommandOptions::WithTimeout(100).Always().Build()));
1446 });
1447
1448 // Capture pid and pre-sleep output.
1449 sleep(1); // Wait a little bit to make sure pid and 1st line were printed.
1450 std::string err = GetCapturedStderr();
1451 EXPECT_THAT(err, StrEq("sleeping for 20s\n"));
1452
1453 CaptureFdOut();
1454 std::vector<std::string> lines = android::base::Split(out, "\n");
1455 ASSERT_EQ(3, (int)lines.size()) << "Invalid lines before sleep: " << out;
1456
1457 int pid = atoi(lines[0].c_str());
1458 EXPECT_THAT(lines[1], StrEq("stdout line1"));
1459 EXPECT_THAT(lines[2], IsEmpty()); // \n
1460
1461 // Then kill the process.
1462 CaptureFdOut();
1463 CaptureStderr();
1464 ASSERT_EQ(0, kill(pid, SIGTERM)) << "failed to kill pid " << pid;
1465 t.join();
1466
1467 // Finally, check output after murder.
1468 CaptureFdOut();
1469 err = GetCapturedStderr();
1470
1471 // out starts with the pid, which is an unknown
1472 EXPECT_THAT(out, EndsWith("stdout line1\n*** command '" + kSimpleCommand +
1473 " --pid --sleep 20' failed: killed by signal 15\n"));
1474 EXPECT_THAT(err, StrEq("*** command '" + kSimpleCommand +
1475 " --pid --sleep 20' failed: killed by signal 15\n"));
1476}
1477
1478TEST_F(DumpstateUtilTest, RunCommandAsRootUserBuild) {
1479 if (!IsStandalone()) {
1480 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1481 // to Shell - need to refactor tests to avoid this problem)
1482 MYLOGE("Skipping DumpstateUtilTest.RunCommandAsRootUserBuild() on test suite\n")
1483 return;
1484 }
1485 CreateFd("RunCommandAsRootUserBuild.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001486 if (!PropertiesHelper::IsUserBuild()) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001487 // Emulates user build if necessarily.
1488 SetBuildType("user");
1489 }
1490
1491 DropRoot();
1492
Felipe Lemef0292972016-11-22 13:57:05 -08001493 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).AsRoot().Build()));
Felipe Leme46b85da2016-11-21 17:40:45 -08001494
1495 // We don't know the exact path of su, so we just check for the 'root ...' commands
1496 EXPECT_THAT(out, StartsWith("Skipping"));
1497 EXPECT_THAT(out, EndsWith("root " + kSimpleCommand + "' on user build.\n"));
1498 EXPECT_THAT(err, IsEmpty());
1499}
1500
1501TEST_F(DumpstateUtilTest, RunCommandAsRootNonUserBuild) {
1502 if (!IsStandalone()) {
1503 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1504 // to Shell - need to refactor tests to avoid this problem)
1505 MYLOGE("Skipping DumpstateUtilTest.RunCommandAsRootNonUserBuild() on test suite\n")
1506 return;
1507 }
1508 CreateFd("RunCommandAsRootNonUserBuild.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001509 if (PropertiesHelper::IsUserBuild()) {
Felipe Leme7447d7c2016-11-03 18:12:22 -07001510 ALOGI("Skipping RunCommandAsRootNonUserBuild on user builds\n");
1511 return;
1512 }
1513
1514 DropRoot();
1515
Felipe Lemef0292972016-11-22 13:57:05 -08001516 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
1517 CommandOptions::WithTimeout(1).AsRoot().Build()));
Felipe Leme7447d7c2016-11-03 18:12:22 -07001518
1519 EXPECT_THAT(out, StrEq("0\nstdout\n"));
1520 EXPECT_THAT(err, StrEq("stderr\n"));
1521}
Felipe Leme46b85da2016-11-21 17:40:45 -08001522
Yifan Hong48e83a12017-10-03 14:10:07 -07001523
1524TEST_F(DumpstateUtilTest, RunCommandAsRootIfAvailableOnUserBuild) {
1525 if (!IsStandalone()) {
1526 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1527 // to Shell - need to refactor tests to avoid this problem)
1528 MYLOGE("Skipping DumpstateUtilTest.RunCommandAsRootIfAvailableOnUserBuild() on test suite\n")
1529 return;
1530 }
1531 CreateFd("RunCommandAsRootIfAvailableOnUserBuild.txt");
1532 if (!PropertiesHelper::IsUserBuild()) {
1533 // Emulates user build if necessarily.
1534 SetBuildType("user");
1535 }
1536
1537 DropRoot();
1538
1539 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
1540 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
1541
1542 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
1543 EXPECT_THAT(err, StrEq("stderr\n"));
1544}
1545
1546TEST_F(DumpstateUtilTest, RunCommandAsRootIfAvailableOnDebugBuild) {
1547 if (!IsStandalone()) {
1548 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1549 // to Shell - need to refactor tests to avoid this problem)
1550 MYLOGE("Skipping DumpstateUtilTest.RunCommandAsRootIfAvailableOnDebugBuild() on test suite\n")
1551 return;
1552 }
1553 CreateFd("RunCommandAsRootIfAvailableOnDebugBuild.txt");
1554 if (PropertiesHelper::IsUserBuild()) {
1555 ALOGI("Skipping RunCommandAsRootNonUserBuild on user builds\n");
1556 return;
1557 }
1558
1559 DropRoot();
1560
1561 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
1562 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
1563
1564 EXPECT_THAT(out, StrEq("0\nstdout\n"));
1565 EXPECT_THAT(err, StrEq("stderr\n"));
1566}
1567
Felipe Leme46b85da2016-11-21 17:40:45 -08001568TEST_F(DumpstateUtilTest, RunCommandDropRoot) {
1569 if (!IsStandalone()) {
1570 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1571 // to Shell - need to refactor tests to avoid this problem)
1572 MYLOGE("Skipping DumpstateUtilTest.RunCommandDropRoot() on test suite\n")
1573 return;
1574 }
1575 CreateFd("RunCommandDropRoot.txt");
1576 // First check root case - only available when running with 'adb root'.
1577 uid_t uid = getuid();
1578 if (uid == 0) {
Felipe Lemef0292972016-11-22 13:57:05 -08001579 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001580 EXPECT_THAT(out, StrEq("0\nstdout\n"));
1581 EXPECT_THAT(err, StrEq("stderr\n"));
1582 return;
1583 }
1584 // Then run dropping root.
Felipe Lemef0292972016-11-22 13:57:05 -08001585 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
Felipe Leme46b85da2016-11-21 17:40:45 -08001586 CommandOptions::WithTimeout(1).DropRoot().Build()));
1587 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
1588 EXPECT_THAT(err, StrEq("drop_root_user(): already running as Shell\nstderr\n"));
1589}
1590
Felipe Lemef0292972016-11-22 13:57:05 -08001591TEST_F(DumpstateUtilTest, DumpFileNotFoundNoTitle) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001592 CreateFd("DumpFileNotFound.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001593 EXPECT_EQ(-1, DumpFile("", "/I/cant/believe/I/exist"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001594 EXPECT_THAT(out,
1595 StrEq("*** Error dumping /I/cant/believe/I/exist: No such file or directory\n"));
1596 EXPECT_THAT(err, IsEmpty());
1597}
1598
Felipe Lemef0292972016-11-22 13:57:05 -08001599TEST_F(DumpstateUtilTest, DumpFileNotFoundWithTitle) {
1600 CreateFd("DumpFileNotFound.txt");
1601 EXPECT_EQ(-1, DumpFile("Y U NO EXIST?", "/I/cant/believe/I/exist"));
1602 EXPECT_THAT(out, StrEq("*** Error dumping /I/cant/believe/I/exist (Y U NO EXIST?): No such "
1603 "file or directory\n"));
1604 EXPECT_THAT(err, IsEmpty());
1605}
1606
Felipe Leme46b85da2016-11-21 17:40:45 -08001607TEST_F(DumpstateUtilTest, DumpFileSingleLine) {
1608 CreateFd("DumpFileSingleLine.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001609 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001610 EXPECT_THAT(err, IsEmpty());
1611 EXPECT_THAT(out, StrEq("I AM LINE1\n")); // dumpstate adds missing newline
1612}
1613
1614TEST_F(DumpstateUtilTest, DumpFileSingleLineWithNewLine) {
1615 CreateFd("DumpFileSingleLineWithNewLine.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001616 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line-with-newline.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001617 EXPECT_THAT(err, IsEmpty());
1618 EXPECT_THAT(out, StrEq("I AM LINE1\n"));
1619}
1620
1621TEST_F(DumpstateUtilTest, DumpFileMultipleLines) {
1622 CreateFd("DumpFileMultipleLines.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001623 EXPECT_EQ(0, DumpFile("", kTestDataPath + "multiple-lines.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001624 EXPECT_THAT(err, IsEmpty());
1625 EXPECT_THAT(out, StrEq("I AM LINE1\nI AM LINE2\nI AM LINE3\n"));
1626}
1627
1628TEST_F(DumpstateUtilTest, DumpFileMultipleLinesWithNewLine) {
1629 CreateFd("DumpFileMultipleLinesWithNewLine.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001630 EXPECT_EQ(0, DumpFile("", kTestDataPath + "multiple-lines-with-newline.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001631 EXPECT_THAT(err, IsEmpty());
1632 EXPECT_THAT(out, StrEq("I AM LINE1\nI AM LINE2\nI AM LINE3\n"));
1633}
1634
Felipe Lemef0292972016-11-22 13:57:05 -08001635TEST_F(DumpstateUtilTest, DumpFileOnDryRunNoTitle) {
1636 CreateFd("DumpFileOnDryRun.txt");
1637 SetDryRun(true);
1638 std::string path = kTestDataPath + "single-line.txt";
1639 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
1640 EXPECT_THAT(err, IsEmpty());
1641 EXPECT_THAT(out, StrEq(path + ": skipped on dry run\n"));
1642}
1643
Felipe Leme46b85da2016-11-21 17:40:45 -08001644TEST_F(DumpstateUtilTest, DumpFileOnDryRun) {
1645 CreateFd("DumpFileOnDryRun.txt");
1646 SetDryRun(true);
1647 std::string path = kTestDataPath + "single-line.txt";
Felipe Lemef0292972016-11-22 13:57:05 -08001648 EXPECT_EQ(0, DumpFile("Might as well dump. Dump!", kTestDataPath + "single-line.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001649 EXPECT_THAT(err, IsEmpty());
Felipe Lemef0292972016-11-22 13:57:05 -08001650 EXPECT_THAT(
1651 out, StartsWith("------ Might as well dump. Dump! (" + kTestDataPath + "single-line.txt:"));
1652 EXPECT_THAT(out, EndsWith("skipped on dry run\n"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001653}
Ecco Park61ffcf72016-10-27 15:46:26 -07001654
Rhed Jao27077b12020-07-14 18:38:08 +08001655class DumpPoolTest : public DumpstateBaseTest {
1656 public:
1657 void SetUp() {
Rhed Jao1c855122020-07-16 17:37:39 +08001658 dump_pool_ = std::make_unique<DumpPool>(kTestDataPath);
Rhed Jao27077b12020-07-14 18:38:08 +08001659 DumpstateBaseTest::SetUp();
1660 CreateOutputFile();
1661 }
1662
1663 void CreateOutputFile() {
1664 out_path_ = kTestDataPath + "out.txt";
1665 out_fd_.reset(TEMP_FAILURE_RETRY(open(out_path_.c_str(),
1666 O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW,
1667 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)));
1668 ASSERT_GE(out_fd_.get(), 0) << "could not create FD for path "
1669 << out_path_;
1670 }
1671
1672 int getTempFileCounts(const std::string& folder) {
1673 int count = 0;
1674 std::unique_ptr<DIR, decltype(&closedir)> dir_ptr(opendir(folder.c_str()),
1675 &closedir);
1676 if (!dir_ptr) {
1677 return -1;
1678 }
1679 int dir_fd = dirfd(dir_ptr.get());
1680 if (dir_fd < 0) {
1681 return -1;
1682 }
1683
1684 struct dirent* de;
1685 while ((de = readdir(dir_ptr.get()))) {
1686 if (de->d_type != DT_REG) {
1687 continue;
1688 }
1689 std::string file_name(de->d_name);
1690 if (file_name.find(DumpPool::PREFIX_TMPFILE_NAME) != 0) {
1691 continue;
1692 }
1693 count++;
1694 }
1695 return count;
1696 }
1697
Rhed Jao1c855122020-07-16 17:37:39 +08001698 void setLogDuration(bool log_duration) {
1699 dump_pool_->setLogDuration(log_duration);
1700 }
1701
1702 std::unique_ptr<DumpPool> dump_pool_;
Rhed Jao27077b12020-07-14 18:38:08 +08001703 android::base::unique_fd out_fd_;
1704 std::string out_path_;
1705};
1706
Rhed Jao1c855122020-07-16 17:37:39 +08001707TEST_F(DumpPoolTest, EnqueueTaskWithFd) {
Rhed Jao27077b12020-07-14 18:38:08 +08001708 auto dump_func_1 = [](int out_fd) {
1709 dprintf(out_fd, "A");
1710 };
1711 auto dump_func_2 = [](int out_fd) {
1712 dprintf(out_fd, "B");
1713 sleep(1);
1714 };
1715 auto dump_func_3 = [](int out_fd) {
1716 dprintf(out_fd, "C");
1717 };
Rhed Jao1c855122020-07-16 17:37:39 +08001718 setLogDuration(/* log_duration = */false);
1719 dump_pool_->enqueueTaskWithFd(/* task_name = */"1", dump_func_1, std::placeholders::_1);
1720 dump_pool_->enqueueTaskWithFd(/* task_name = */"2", dump_func_2, std::placeholders::_1);
1721 dump_pool_->enqueueTaskWithFd(/* task_name = */"3", dump_func_3, std::placeholders::_1);
Rhed Jao27077b12020-07-14 18:38:08 +08001722
Rhed Jao1c855122020-07-16 17:37:39 +08001723 dump_pool_->waitForTask("1", "", out_fd_.get());
1724 dump_pool_->waitForTask("2", "", out_fd_.get());
1725 dump_pool_->waitForTask("3", "", out_fd_.get());
1726 dump_pool_->shutdown();
Rhed Jao27077b12020-07-14 18:38:08 +08001727
1728 std::string result;
1729 ReadFileToString(out_path_, &result);
1730 EXPECT_THAT(result, StrEq("A\nB\nC\n"));
1731 EXPECT_THAT(getTempFileCounts(kTestDataPath), Eq(0));
Rhed Jao1c855122020-07-16 17:37:39 +08001732}
1733
1734TEST_F(DumpPoolTest, EnqueueTask_withDurationLog) {
1735 bool run_1 = false;
1736 auto dump_func_1 = [&]() {
1737 run_1 = true;
1738 };
1739
1740 dump_pool_->enqueueTask(/* task_name = */"1", dump_func_1);
1741 dump_pool_->waitForTask("1", "", out_fd_.get());
1742 dump_pool_->shutdown();
1743
1744 std::string result;
1745 ReadFileToString(out_path_, &result);
1746 EXPECT_TRUE(run_1);
1747 EXPECT_THAT(result, StrEq("------ 0.000s was the duration of '1' ------\n"));
1748 EXPECT_THAT(getTempFileCounts(kTestDataPath), Eq(0));
Rhed Jao27077b12020-07-14 18:38:08 +08001749}
1750
Rhed Jao4875aa62020-07-20 17:46:29 +08001751class TaskQueueTest : public DumpstateBaseTest {
1752public:
1753 void SetUp() {
1754 DumpstateBaseTest::SetUp();
1755 }
1756
1757 TaskQueue task_queue_;
1758};
1759
1760TEST_F(TaskQueueTest, runTask) {
1761 bool is_task1_run = false;
1762 bool is_task2_run = false;
1763 auto task_1 = [&](bool task_cancelled) {
1764 if (task_cancelled) {
1765 return;
1766 }
1767 is_task1_run = true;
1768 };
1769 auto task_2 = [&](bool task_cancelled) {
1770 if (task_cancelled) {
1771 return;
1772 }
1773 is_task2_run = true;
1774 };
1775 task_queue_.add(task_1, std::placeholders::_1);
1776 task_queue_.add(task_2, std::placeholders::_1);
1777
1778 task_queue_.run(/* do_cancel = */false);
1779
1780 EXPECT_TRUE(is_task1_run);
1781 EXPECT_TRUE(is_task2_run);
1782}
1783
1784TEST_F(TaskQueueTest, runTask_withCancelled) {
1785 bool is_task1_cancelled = false;
1786 bool is_task2_cancelled = false;
1787 auto task_1 = [&](bool task_cancelled) {
1788 is_task1_cancelled = task_cancelled;
1789 };
1790 auto task_2 = [&](bool task_cancelled) {
1791 is_task2_cancelled = task_cancelled;
1792 };
1793 task_queue_.add(task_1, std::placeholders::_1);
1794 task_queue_.add(task_2, std::placeholders::_1);
1795
1796 task_queue_.run(/* do_cancel = */true);
1797
1798 EXPECT_TRUE(is_task1_cancelled);
1799 EXPECT_TRUE(is_task2_cancelled);
1800}
1801
Rhed Jao27077b12020-07-14 18:38:08 +08001802
Felipe Leme47e9be22016-12-21 15:37:07 -08001803} // namespace dumpstate
1804} // namespace os
1805} // namespace android