blob: bc3da1f442754d6bdffd5491a5c67f70f77110b1 [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"
24
25#include <gmock/gmock.h>
26#include <gtest/gtest.h>
27
Felipe Leme46b85da2016-11-21 17:40:45 -080028#include <fcntl.h>
Felipe Leme4c2d6632016-09-28 14:32:00 -070029#include <libgen.h>
Felipe Lemefd8affa2016-09-30 17:38:57 -070030#include <signal.h>
31#include <sys/types.h>
Felipe Leme4c2d6632016-09-28 14:32:00 -070032#include <unistd.h>
Felipe Lemefd8affa2016-09-30 17:38:57 -070033#include <thread>
Felipe Leme4c2d6632016-09-28 14:32:00 -070034
35#include <android-base/file.h>
Felipe Lemed80e6b62016-10-03 13:08:14 -070036#include <android-base/properties.h>
37#include <android-base/stringprintf.h>
Felipe Lemefd8affa2016-09-30 17:38:57 -070038#include <android-base/strings.h>
Abhijeet Kaure370d682019-10-01 16:49:30 +010039#include <android-base/unique_fd.h>
Hunter Knepshield8540faf2020-02-04 19:47:20 -080040#include <android/hardware/dumpstate/1.1/types.h>
41#include <cutils/properties.h>
Felipe Leme4c2d6632016-09-28 14:32:00 -070042
Felipe Leme47e9be22016-12-21 15:37:07 -080043namespace android {
44namespace os {
45namespace dumpstate {
Felipe Lemed80e6b62016-10-03 13:08:14 -070046
Hunter Knepshield8540faf2020-02-04 19:47:20 -080047using ::android::hardware::dumpstate::V1_1::DumpstateMode;
Felipe Leme4c2d6632016-09-28 14:32:00 -070048using ::testing::EndsWith;
Felipe Leme46b85da2016-11-21 17:40:45 -080049using ::testing::HasSubstr;
Felipe Leme4c2d6632016-09-28 14:32:00 -070050using ::testing::IsEmpty;
Hunter Knepshield8540faf2020-02-04 19:47:20 -080051using ::testing::IsNull;
Felipe Leme009ecbb2016-11-07 10:18:44 -080052using ::testing::NotNull;
Felipe Leme4c2d6632016-09-28 14:32:00 -070053using ::testing::StartsWith;
Hunter Knepshield8540faf2020-02-04 19:47:20 -080054using ::testing::StrEq;
Felipe Leme4c2d6632016-09-28 14:32:00 -070055using ::testing::Test;
56using ::testing::internal::CaptureStderr;
57using ::testing::internal::CaptureStdout;
58using ::testing::internal::GetCapturedStderr;
59using ::testing::internal::GetCapturedStdout;
60
Nandana Dutt3f8c7172018-09-25 12:01:54 +010061#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
62
Felipe Leme75876a22016-10-27 16:31:27 -070063class DumpstateListenerMock : public IDumpstateListener {
64 public:
Nandana Dutta6a28bd2019-01-14 16:54:38 +000065 MOCK_METHOD1(onProgress, binder::Status(int32_t progress));
66 MOCK_METHOD1(onError, binder::Status(int32_t error_code));
Nandana Duttcc4ead82019-01-23 08:29:23 +000067 MOCK_METHOD0(onFinished, binder::Status());
Paul Chang0d2aad72020-02-13 20:04:03 +080068 MOCK_METHOD1(onScreenshotTaken, binder::Status(bool success));
Paul Changeb4b4642020-05-28 22:05:47 +080069 MOCK_METHOD0(onUiIntensiveBugreportDumpsFinished, binder::Status());
Felipe Leme75876a22016-10-27 16:31:27 -070070
71 protected:
72 MOCK_METHOD0(onAsBinder, IBinder*());
73};
74
Felipe Leme46b85da2016-11-21 17:40:45 -080075static int calls_;
76
Felipe Leme7447d7c2016-11-03 18:12:22 -070077// Base class for all tests in this file
78class DumpstateBaseTest : public Test {
Felipe Leme46b85da2016-11-21 17:40:45 -080079 public:
80 virtual void SetUp() override {
81 calls_++;
Felipe Lemef0292972016-11-22 13:57:05 -080082 SetDryRun(false);
Felipe Leme46b85da2016-11-21 17:40:45 -080083 }
84
Felipe Lemef0292972016-11-22 13:57:05 -080085 void SetDryRun(bool dry_run) const {
86 PropertiesHelper::dry_run_ = dry_run;
87 }
88
89 void SetBuildType(const std::string& build_type) const {
90 PropertiesHelper::build_type_ = build_type;
91 }
92
Nandana Dutt4b392be2018-11-02 16:17:05 +000093 void SetUnroot(bool unroot) const {
94 PropertiesHelper::unroot_ = unroot;
95 }
96
Felipe Lemef0292972016-11-22 13:57:05 -080097 bool IsStandalone() const {
Felipe Leme46b85da2016-11-21 17:40:45 -080098 return calls_ == 1;
99 }
100
Felipe Lemef0292972016-11-22 13:57:05 -0800101 void DropRoot() const {
102 DropRootUser();
Felipe Leme46b85da2016-11-21 17:40:45 -0800103 uid_t uid = getuid();
104 ASSERT_EQ(2000, (int)uid);
105 }
106
Felipe Leme7447d7c2016-11-03 18:12:22 -0700107 protected:
108 const std::string kTestPath = dirname(android::base::GetExecutablePath().c_str());
Dan Shie177e8e2019-06-20 11:08:14 -0700109 const std::string kTestDataPath = kTestPath + "/tests/testdata/";
110 const std::string kSimpleCommand = kTestPath + "/dumpstate_test_fixture";
Felipe Leme7447d7c2016-11-03 18:12:22 -0700111 const std::string kEchoCommand = "/system/bin/echo";
112
113 /*
114 * Copies a text file fixture to a temporary file, returning it's path.
115 *
116 * Useful in cases where the test case changes the content of the tile.
117 */
118 std::string CopyTextFileFixture(const std::string& relative_name) {
119 std::string from = kTestDataPath + relative_name;
120 // Not using TemporaryFile because it's deleted at the end, and it's useful to keep it
121 // around for poking when the test fails.
122 std::string to = kTestDataPath + relative_name + ".tmp";
123 ALOGD("CopyTextFileFixture: from %s to %s\n", from.c_str(), to.c_str());
124 android::base::RemoveFileIfExists(to);
125 CopyTextFile(from, to);
126 return to.c_str();
127 }
128
Felipe Leme46b85da2016-11-21 17:40:45 -0800129 // Need functions that returns void to use assertions -
Felipe Leme7447d7c2016-11-03 18:12:22 -0700130 // https://github.com/google/googletest/blob/master/googletest/docs/AdvancedGuide.md#assertion-placement
Felipe Leme46b85da2016-11-21 17:40:45 -0800131 void ReadFileToString(const std::string& path, std::string* content) {
132 ASSERT_TRUE(android::base::ReadFileToString(path, content))
133 << "could not read contents from " << path;
134 }
135 void WriteStringToFile(const std::string& content, const std::string& path) {
136 ASSERT_TRUE(android::base::WriteStringToFile(content, path))
137 << "could not write contents to " << path;
138 }
139
140 private:
Felipe Leme7447d7c2016-11-03 18:12:22 -0700141 void CopyTextFile(const std::string& from, const std::string& to) {
142 std::string content;
Felipe Leme46b85da2016-11-21 17:40:45 -0800143 ReadFileToString(from, &content);
144 WriteStringToFile(content, to);
Felipe Leme7447d7c2016-11-03 18:12:22 -0700145 }
146};
147
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100148class DumpOptionsTest : public Test {
149 public:
150 virtual ~DumpOptionsTest() {
151 }
152 virtual void SetUp() {
153 options_ = Dumpstate::DumpOptions();
154 }
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000155 void TearDown() {
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000156 }
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100157 Dumpstate::DumpOptions options_;
Abhijeet Kaure370d682019-10-01 16:49:30 +0100158 android::base::unique_fd fd;
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100159};
160
161TEST_F(DumpOptionsTest, InitializeNone) {
162 // clang-format off
163 char* argv[] = {
164 const_cast<char*>("dumpstate")
165 };
166 // clang-format on
167
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100168 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
169
170 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
Nandana Dutt58d72e22018-11-16 10:30:48 +0000171
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100172 EXPECT_FALSE(options_.do_add_date);
173 EXPECT_FALSE(options_.do_zip_file);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100174 EXPECT_FALSE(options_.use_socket);
175 EXPECT_FALSE(options_.use_control_socket);
176 EXPECT_FALSE(options_.show_header_only);
177 EXPECT_TRUE(options_.do_vibrate);
Paul Chang0d2aad72020-02-13 20:04:03 +0800178 EXPECT_FALSE(options_.do_screenshot);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100179 EXPECT_FALSE(options_.do_progress_updates);
180 EXPECT_FALSE(options_.is_remote_mode);
mhasankf56bbb22020-05-26 18:02:39 -0700181 EXPECT_FALSE(options_.arc_only);
Hunter Knepshield8540faf2020-02-04 19:47:20 -0800182 EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::DEFAULT);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000183}
184
185TEST_F(DumpOptionsTest, InitializeAdbBugreport) {
186 // clang-format off
187 char* argv[] = {
188 const_cast<char*>("dumpstatez"),
189 const_cast<char*>("-S"),
190 const_cast<char*>("-d"),
191 const_cast<char*>("-z"),
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000192 };
193 // clang-format on
194
195 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
196
197 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
198 EXPECT_TRUE(options_.do_add_date);
199 EXPECT_TRUE(options_.do_zip_file);
200 EXPECT_TRUE(options_.use_control_socket);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000201
202 // Other options retain default values
203 EXPECT_TRUE(options_.do_vibrate);
204 EXPECT_FALSE(options_.show_header_only);
Paul Chang0d2aad72020-02-13 20:04:03 +0800205 EXPECT_FALSE(options_.do_screenshot);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000206 EXPECT_FALSE(options_.do_progress_updates);
207 EXPECT_FALSE(options_.is_remote_mode);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000208 EXPECT_FALSE(options_.use_socket);
mhasankf56bbb22020-05-26 18:02:39 -0700209 EXPECT_FALSE(options_.arc_only);
Hunter Knepshield8540faf2020-02-04 19:47:20 -0800210 EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::DEFAULT);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000211}
212
213TEST_F(DumpOptionsTest, InitializeAdbShellBugreport) {
214 // clang-format off
215 char* argv[] = {
216 const_cast<char*>("dumpstate"),
217 const_cast<char*>("-s"),
218 };
219 // clang-format on
220
221 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
222
223 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
224 EXPECT_TRUE(options_.use_socket);
225
226 // Other options retain default values
227 EXPECT_TRUE(options_.do_vibrate);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000228 EXPECT_FALSE(options_.do_add_date);
229 EXPECT_FALSE(options_.do_zip_file);
230 EXPECT_FALSE(options_.use_control_socket);
231 EXPECT_FALSE(options_.show_header_only);
Paul Chang0d2aad72020-02-13 20:04:03 +0800232 EXPECT_FALSE(options_.do_screenshot);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000233 EXPECT_FALSE(options_.do_progress_updates);
234 EXPECT_FALSE(options_.is_remote_mode);
mhasankf56bbb22020-05-26 18:02:39 -0700235 EXPECT_FALSE(options_.arc_only);
Hunter Knepshield8540faf2020-02-04 19:47:20 -0800236 EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::DEFAULT);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000237}
238
239TEST_F(DumpOptionsTest, InitializeFullBugReport) {
Paul Changf59c2b72020-03-10 02:08:55 +0800240 options_.Initialize(Dumpstate::BugreportMode::BUGREPORT_FULL, fd, fd, true);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000241 EXPECT_TRUE(options_.do_add_date);
Paul Chang0d2aad72020-02-13 20:04:03 +0800242 EXPECT_TRUE(options_.do_screenshot);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000243 EXPECT_TRUE(options_.do_zip_file);
Hunter Knepshield8540faf2020-02-04 19:47:20 -0800244 EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::FULL);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000245
246 // Other options retain default values
247 EXPECT_TRUE(options_.do_vibrate);
248 EXPECT_FALSE(options_.use_control_socket);
249 EXPECT_FALSE(options_.show_header_only);
250 EXPECT_FALSE(options_.do_progress_updates);
251 EXPECT_FALSE(options_.is_remote_mode);
252 EXPECT_FALSE(options_.use_socket);
253 EXPECT_FALSE(options_.do_start_service);
mhasankf56bbb22020-05-26 18:02:39 -0700254 EXPECT_FALSE(options_.arc_only);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000255}
256
257TEST_F(DumpOptionsTest, InitializeInteractiveBugReport) {
Paul Changf59c2b72020-03-10 02:08:55 +0800258 options_.Initialize(Dumpstate::BugreportMode::BUGREPORT_INTERACTIVE, fd, fd, true);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000259 EXPECT_TRUE(options_.do_add_date);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000260 EXPECT_TRUE(options_.do_zip_file);
261 EXPECT_TRUE(options_.do_progress_updates);
262 EXPECT_TRUE(options_.do_start_service);
Paul Chang0d2aad72020-02-13 20:04:03 +0800263 EXPECT_TRUE(options_.do_screenshot);
Hunter Knepshield8540faf2020-02-04 19:47:20 -0800264 EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::INTERACTIVE);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000265
266 // Other options retain default values
267 EXPECT_TRUE(options_.do_vibrate);
268 EXPECT_FALSE(options_.use_control_socket);
269 EXPECT_FALSE(options_.show_header_only);
270 EXPECT_FALSE(options_.is_remote_mode);
271 EXPECT_FALSE(options_.use_socket);
mhasankf56bbb22020-05-26 18:02:39 -0700272 EXPECT_FALSE(options_.arc_only);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000273}
274
275TEST_F(DumpOptionsTest, InitializeRemoteBugReport) {
Paul Changf59c2b72020-03-10 02:08:55 +0800276 options_.Initialize(Dumpstate::BugreportMode::BUGREPORT_REMOTE, fd, fd, false);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000277 EXPECT_TRUE(options_.do_add_date);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000278 EXPECT_TRUE(options_.do_zip_file);
279 EXPECT_TRUE(options_.is_remote_mode);
280 EXPECT_FALSE(options_.do_vibrate);
Paul Chang0d2aad72020-02-13 20:04:03 +0800281 EXPECT_FALSE(options_.do_screenshot);
Hunter Knepshield8540faf2020-02-04 19:47:20 -0800282 EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::REMOTE);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000283
284 // Other options retain default values
285 EXPECT_FALSE(options_.use_control_socket);
286 EXPECT_FALSE(options_.show_header_only);
287 EXPECT_FALSE(options_.do_progress_updates);
288 EXPECT_FALSE(options_.use_socket);
mhasankf56bbb22020-05-26 18:02:39 -0700289 EXPECT_FALSE(options_.arc_only);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000290}
291
292TEST_F(DumpOptionsTest, InitializeWearBugReport) {
Paul Changf59c2b72020-03-10 02:08:55 +0800293 options_.Initialize(Dumpstate::BugreportMode::BUGREPORT_WEAR, fd, fd, true);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000294 EXPECT_TRUE(options_.do_add_date);
Paul Chang0d2aad72020-02-13 20:04:03 +0800295 EXPECT_TRUE(options_.do_screenshot);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000296 EXPECT_TRUE(options_.do_zip_file);
297 EXPECT_TRUE(options_.do_progress_updates);
298 EXPECT_TRUE(options_.do_start_service);
Hunter Knepshield8540faf2020-02-04 19:47:20 -0800299 EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::WEAR);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000300
301 // Other options retain default values
302 EXPECT_TRUE(options_.do_vibrate);
303 EXPECT_FALSE(options_.use_control_socket);
304 EXPECT_FALSE(options_.show_header_only);
305 EXPECT_FALSE(options_.is_remote_mode);
306 EXPECT_FALSE(options_.use_socket);
mhasankf56bbb22020-05-26 18:02:39 -0700307 EXPECT_FALSE(options_.arc_only);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000308}
309
310TEST_F(DumpOptionsTest, InitializeTelephonyBugReport) {
Paul Changf59c2b72020-03-10 02:08:55 +0800311 options_.Initialize(Dumpstate::BugreportMode::BUGREPORT_TELEPHONY, fd, fd, false);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000312 EXPECT_TRUE(options_.do_add_date);
Paul Chang0d2aad72020-02-13 20:04:03 +0800313 EXPECT_FALSE(options_.do_screenshot);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000314 EXPECT_TRUE(options_.do_zip_file);
315 EXPECT_TRUE(options_.telephony_only);
Hunter Knepshield820f9bc2020-02-05 20:10:53 -0800316 EXPECT_TRUE(options_.do_progress_updates);
Hunter Knepshield8540faf2020-02-04 19:47:20 -0800317 EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::CONNECTIVITY);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000318
319 // Other options retain default values
320 EXPECT_TRUE(options_.do_vibrate);
321 EXPECT_FALSE(options_.use_control_socket);
322 EXPECT_FALSE(options_.show_header_only);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000323 EXPECT_FALSE(options_.is_remote_mode);
324 EXPECT_FALSE(options_.use_socket);
mhasankf56bbb22020-05-26 18:02:39 -0700325 EXPECT_FALSE(options_.arc_only);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000326}
327
328TEST_F(DumpOptionsTest, InitializeWifiBugReport) {
Paul Changf59c2b72020-03-10 02:08:55 +0800329 options_.Initialize(Dumpstate::BugreportMode::BUGREPORT_WIFI, fd, fd, false);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000330 EXPECT_TRUE(options_.do_add_date);
Paul Chang0d2aad72020-02-13 20:04:03 +0800331 EXPECT_FALSE(options_.do_screenshot);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000332 EXPECT_TRUE(options_.do_zip_file);
333 EXPECT_TRUE(options_.wifi_only);
Hunter Knepshield8540faf2020-02-04 19:47:20 -0800334 EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::WIFI);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000335
336 // Other options retain default values
337 EXPECT_TRUE(options_.do_vibrate);
338 EXPECT_FALSE(options_.use_control_socket);
339 EXPECT_FALSE(options_.show_header_only);
340 EXPECT_FALSE(options_.do_progress_updates);
341 EXPECT_FALSE(options_.is_remote_mode);
342 EXPECT_FALSE(options_.use_socket);
mhasankf56bbb22020-05-26 18:02:39 -0700343 EXPECT_FALSE(options_.arc_only);
344}
345
346TEST_F(DumpOptionsTest, InitializeArcOnlyBugreport) {
347 // clang-format off
348 char* argv[] = {
349 const_cast<char*>("dumpstatez"),
350 const_cast<char*>("-S"),
351 const_cast<char*>("-d"),
352 const_cast<char*>("-z"),
353 const_cast<char*>("-q"),
354 const_cast<char*>("-A")
355 };
356 // clang-format on
357
358 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
359
360 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
361 EXPECT_TRUE(options_.do_add_date);
362 EXPECT_TRUE(options_.do_zip_file);
363 EXPECT_TRUE(options_.use_control_socket);
364 EXPECT_FALSE(options_.do_vibrate);
365 EXPECT_TRUE(options_.arc_only);
366
367 // Other options retain default values
368 EXPECT_FALSE(options_.show_header_only);
369 EXPECT_FALSE(options_.do_screenshot);
370 EXPECT_FALSE(options_.do_progress_updates);
371 EXPECT_FALSE(options_.is_remote_mode);
372 EXPECT_FALSE(options_.use_socket);
373 EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::DEFAULT);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000374}
375
376TEST_F(DumpOptionsTest, InitializeDefaultBugReport) {
377 // default: commandline options are not overridden
378 // clang-format off
379 char* argv[] = {
380 const_cast<char*>("bugreport"),
381 const_cast<char*>("-d"),
382 const_cast<char*>("-p"),
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000383 const_cast<char*>("-z"),
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000384 };
385 // clang-format on
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000386 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
387
388 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
389 EXPECT_TRUE(options_.do_add_date);
Paul Chang0d2aad72020-02-13 20:04:03 +0800390 EXPECT_TRUE(options_.do_screenshot);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000391 EXPECT_TRUE(options_.do_zip_file);
Hunter Knepshield8540faf2020-02-04 19:47:20 -0800392 EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::DEFAULT);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000393
394 // Other options retain default values
395 EXPECT_TRUE(options_.do_vibrate);
396 EXPECT_FALSE(options_.use_control_socket);
397 EXPECT_FALSE(options_.show_header_only);
398 EXPECT_FALSE(options_.do_progress_updates);
399 EXPECT_FALSE(options_.is_remote_mode);
400 EXPECT_FALSE(options_.use_socket);
401 EXPECT_FALSE(options_.wifi_only);
mhasankf56bbb22020-05-26 18:02:39 -0700402 EXPECT_FALSE(options_.arc_only);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100403}
404
405TEST_F(DumpOptionsTest, InitializePartial1) {
406 // clang-format off
407 char* argv[] = {
408 const_cast<char*>("dumpstate"),
409 const_cast<char*>("-d"),
410 const_cast<char*>("-z"),
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100411 const_cast<char*>("-s"),
412 const_cast<char*>("-S"),
413
414 };
415 // clang-format on
416
417 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
418
419 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
420 EXPECT_TRUE(options_.do_add_date);
421 EXPECT_TRUE(options_.do_zip_file);
422 // TODO: Maybe we should trim the filename
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100423 EXPECT_TRUE(options_.use_socket);
424 EXPECT_TRUE(options_.use_control_socket);
425
426 // Other options retain default values
427 EXPECT_FALSE(options_.show_header_only);
428 EXPECT_TRUE(options_.do_vibrate);
Paul Chang0d2aad72020-02-13 20:04:03 +0800429 EXPECT_FALSE(options_.do_screenshot);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100430 EXPECT_FALSE(options_.do_progress_updates);
431 EXPECT_FALSE(options_.is_remote_mode);
mhasankf56bbb22020-05-26 18:02:39 -0700432 EXPECT_FALSE(options_.arc_only);
Hunter Knepshield8540faf2020-02-04 19:47:20 -0800433 EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::DEFAULT);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100434}
435
436TEST_F(DumpOptionsTest, InitializePartial2) {
437 // clang-format off
438 char* argv[] = {
439 const_cast<char*>("dumpstate"),
440 const_cast<char*>("-v"),
441 const_cast<char*>("-q"),
442 const_cast<char*>("-p"),
443 const_cast<char*>("-P"),
444 const_cast<char*>("-R"),
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100445 };
446 // clang-format on
447
448 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
449
450 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
451 EXPECT_TRUE(options_.show_header_only);
452 EXPECT_FALSE(options_.do_vibrate);
Paul Chang0d2aad72020-02-13 20:04:03 +0800453 EXPECT_TRUE(options_.do_screenshot);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100454 EXPECT_TRUE(options_.do_progress_updates);
455 EXPECT_TRUE(options_.is_remote_mode);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100456
457 // Other options retain default values
458 EXPECT_FALSE(options_.do_add_date);
459 EXPECT_FALSE(options_.do_zip_file);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100460 EXPECT_FALSE(options_.use_socket);
461 EXPECT_FALSE(options_.use_control_socket);
mhasankf56bbb22020-05-26 18:02:39 -0700462 EXPECT_FALSE(options_.arc_only);
Hunter Knepshield8540faf2020-02-04 19:47:20 -0800463 EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::DEFAULT);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100464}
465
466TEST_F(DumpOptionsTest, InitializeHelp) {
467 // clang-format off
468 char* argv[] = {
469 const_cast<char*>("dumpstate"),
470 const_cast<char*>("-h")
471 };
472 // clang-format on
473
474 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
475
476 // -h is for help.
477 EXPECT_EQ(status, Dumpstate::RunStatus::HELP);
478}
479
480TEST_F(DumpOptionsTest, InitializeUnknown) {
481 // clang-format off
482 char* argv[] = {
483 const_cast<char*>("dumpstate"),
484 const_cast<char*>("-u") // unknown flag
485 };
486 // clang-format on
487
488 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
489
490 // -u is unknown.
491 EXPECT_EQ(status, Dumpstate::RunStatus::INVALID_INPUT);
492}
493
494TEST_F(DumpOptionsTest, ValidateOptionsNeedOutfile1) {
495 options_.do_zip_file = true;
Nandana Dutt9a76d202019-01-21 15:56:48 +0000496 // Writing to socket = !writing to file.
497 options_.use_socket = true;
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100498 EXPECT_FALSE(options_.ValidateOptions());
Nandana Dutt9a76d202019-01-21 15:56:48 +0000499
500 options_.use_socket = false;
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100501 EXPECT_TRUE(options_.ValidateOptions());
502}
503
504TEST_F(DumpOptionsTest, ValidateOptionsNeedOutfile2) {
Abhijeet Kaure370d682019-10-01 16:49:30 +0100505 options_.do_progress_updates = true;
Nandana Dutt9a76d202019-01-21 15:56:48 +0000506 // Writing to socket = !writing to file.
507 options_.use_socket = true;
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100508 EXPECT_FALSE(options_.ValidateOptions());
Nandana Dutt9a76d202019-01-21 15:56:48 +0000509
510 options_.use_socket = false;
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100511 EXPECT_TRUE(options_.ValidateOptions());
512}
513
514TEST_F(DumpOptionsTest, ValidateOptionsNeedZipfile) {
515 options_.use_control_socket = true;
516 EXPECT_FALSE(options_.ValidateOptions());
517
518 options_.do_zip_file = true;
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100519 EXPECT_TRUE(options_.ValidateOptions());
520}
521
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100522TEST_F(DumpOptionsTest, ValidateOptionsRemoteMode) {
523 options_.is_remote_mode = true;
524 EXPECT_FALSE(options_.ValidateOptions());
525
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100526 options_.do_zip_file = true;
527 options_.do_add_date = true;
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100528 EXPECT_TRUE(options_.ValidateOptions());
529}
530
Felipe Leme7447d7c2016-11-03 18:12:22 -0700531class DumpstateTest : public DumpstateBaseTest {
Felipe Leme4c2d6632016-09-28 14:32:00 -0700532 public:
533 void SetUp() {
Felipe Leme46b85da2016-11-21 17:40:45 -0800534 DumpstateBaseTest::SetUp();
Felipe Leme4c2d6632016-09-28 14:32:00 -0700535 SetDryRun(false);
Felipe Lemed80e6b62016-10-03 13:08:14 -0700536 SetBuildType(android::base::GetProperty("ro.build.type", "(unknown)"));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700537 ds.progress_.reset(new Progress());
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100538 ds.options_.reset(new Dumpstate::DumpOptions());
Felipe Leme4c2d6632016-09-28 14:32:00 -0700539 }
540
541 // Runs a command and capture `stdout` and `stderr`.
Felipe Leme9a523ae2016-10-20 15:10:33 -0700542 int RunCommand(const std::string& title, const std::vector<std::string>& full_command,
Felipe Leme4c2d6632016-09-28 14:32:00 -0700543 const CommandOptions& options = CommandOptions::DEFAULT) {
544 CaptureStdout();
545 CaptureStderr();
Felipe Leme9a523ae2016-10-20 15:10:33 -0700546 int status = ds.RunCommand(title, full_command, options);
Felipe Leme4c2d6632016-09-28 14:32:00 -0700547 out = GetCapturedStdout();
548 err = GetCapturedStderr();
549 return status;
550 }
551
Felipe Lemecef02982016-10-03 17:22:22 -0700552 // Dumps a file and capture `stdout` and `stderr`.
553 int DumpFile(const std::string& title, const std::string& path) {
554 CaptureStdout();
555 CaptureStderr();
556 int status = ds.DumpFile(title, path);
557 out = GetCapturedStdout();
558 err = GetCapturedStderr();
559 return status;
560 }
561
Nandana Dutt402a8392019-06-14 14:25:13 +0100562 void SetProgress(long progress, long initial_max) {
563 ds.last_reported_percent_progress_ = 0;
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100564 ds.options_->do_progress_updates = true;
Felipe Leme7447d7c2016-11-03 18:12:22 -0700565 ds.progress_.reset(new Progress(initial_max, progress, 1.2));
566 }
567
Abhijeet Kaured5d6a62019-10-07 15:02:05 +0100568 std::string GetProgressMessage(int progress, int max,
569 int old_max = 0, bool update_progress = true) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700570 EXPECT_EQ(progress, ds.progress_->Get()) << "invalid progress";
571 EXPECT_EQ(max, ds.progress_->GetMax()) << "invalid max";
Felipe Leme75876a22016-10-27 16:31:27 -0700572
Felipe Leme7447d7c2016-11-03 18:12:22 -0700573 bool max_increased = old_max > 0;
Felipe Leme75876a22016-10-27 16:31:27 -0700574
Felipe Leme009ecbb2016-11-07 10:18:44 -0800575 std::string message = "";
Felipe Leme75876a22016-10-27 16:31:27 -0700576 if (max_increased) {
Felipe Leme009ecbb2016-11-07 10:18:44 -0800577 message =
Felipe Leme7447d7c2016-11-03 18:12:22 -0700578 android::base::StringPrintf("Adjusting max progress from %d to %d\n", old_max, max);
Felipe Leme75876a22016-10-27 16:31:27 -0700579 }
580
Felipe Leme009ecbb2016-11-07 10:18:44 -0800581 if (update_progress) {
Abhijeet Kaured5d6a62019-10-07 15:02:05 +0100582 message += android::base::StringPrintf("Setting progress: %d/%d (%d%%)\n",
583 progress, max, (100 * progress / max));
Felipe Leme009ecbb2016-11-07 10:18:44 -0800584 }
585
586 return message;
Felipe Lemed80e6b62016-10-03 13:08:14 -0700587 }
588
Felipe Leme4c2d6632016-09-28 14:32:00 -0700589 // `stdout` and `stderr` from the last command ran.
590 std::string out, err;
591
Felipe Lemefd8affa2016-09-30 17:38:57 -0700592 Dumpstate& ds = Dumpstate::GetInstance();
Felipe Leme4c2d6632016-09-28 14:32:00 -0700593};
594
595TEST_F(DumpstateTest, RunCommandNoArgs) {
596 EXPECT_EQ(-1, RunCommand("", {}));
597}
598
599TEST_F(DumpstateTest, RunCommandNoTitle) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700600 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700601 EXPECT_THAT(out, StrEq("stdout\n"));
602 EXPECT_THAT(err, StrEq("stderr\n"));
603}
604
605TEST_F(DumpstateTest, RunCommandWithTitle) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700606 EXPECT_EQ(0, RunCommand("I AM GROOT", {kSimpleCommand}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700607 EXPECT_THAT(err, StrEq("stderr\n"));
Greg Kaiser3a811c12019-05-21 12:48:59 -0700608 // The duration may not get output, depending on how long it takes,
609 // so we just check the prefix.
Felipe Lemefd8affa2016-09-30 17:38:57 -0700610 EXPECT_THAT(out,
Nandana Dutt47527b52019-03-29 15:34:36 +0000611 StartsWith("------ I AM GROOT (" + kSimpleCommand + ") ------\nstdout\n"));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700612}
613
Felipe Lemefd8affa2016-09-30 17:38:57 -0700614TEST_F(DumpstateTest, RunCommandWithLoggingMessage) {
Felipe Leme4c2d6632016-09-28 14:32:00 -0700615 EXPECT_EQ(
Felipe Leme7447d7c2016-11-03 18:12:22 -0700616 0, RunCommand("", {kSimpleCommand},
Felipe Lemefd8affa2016-09-30 17:38:57 -0700617 CommandOptions::WithTimeout(10).Log("COMMAND, Y U NO LOG FIRST?").Build()));
618 EXPECT_THAT(out, StrEq("stdout\n"));
619 EXPECT_THAT(err, StrEq("COMMAND, Y U NO LOG FIRST?stderr\n"));
620}
621
622TEST_F(DumpstateTest, RunCommandRedirectStderr) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700623 EXPECT_EQ(0, RunCommand("", {kSimpleCommand},
Felipe Lemefd8affa2016-09-30 17:38:57 -0700624 CommandOptions::WithTimeout(10).RedirectStderr().Build()));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700625 EXPECT_THAT(out, IsEmpty());
Felipe Lemefd8affa2016-09-30 17:38:57 -0700626 EXPECT_THAT(err, StrEq("stdout\nstderr\n"));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700627}
628
629TEST_F(DumpstateTest, RunCommandWithOneArg) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700630 EXPECT_EQ(0, RunCommand("", {kEchoCommand, "one"}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700631 EXPECT_THAT(err, IsEmpty());
632 EXPECT_THAT(out, StrEq("one\n"));
633}
634
Felipe Lemefd8affa2016-09-30 17:38:57 -0700635TEST_F(DumpstateTest, RunCommandWithMultipleArgs) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700636 EXPECT_EQ(0, RunCommand("", {kEchoCommand, "one", "is", "the", "loniest", "number"}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700637 EXPECT_THAT(err, IsEmpty());
638 EXPECT_THAT(out, StrEq("one is the loniest number\n"));
639}
640
641TEST_F(DumpstateTest, RunCommandDryRun) {
642 SetDryRun(true);
Felipe Leme7447d7c2016-11-03 18:12:22 -0700643 EXPECT_EQ(0, RunCommand("I AM GROOT", {kSimpleCommand}));
Greg Kaiser3a811c12019-05-21 12:48:59 -0700644 // The duration may not get output, depending on how long it takes,
645 // so we just check the prefix.
Felipe Leme7447d7c2016-11-03 18:12:22 -0700646 EXPECT_THAT(out, StartsWith("------ I AM GROOT (" + kSimpleCommand +
Nandana Dutt47527b52019-03-29 15:34:36 +0000647 ") ------\n\t(skipped on dry run)\n"));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700648 EXPECT_THAT(err, IsEmpty());
649}
650
651TEST_F(DumpstateTest, RunCommandDryRunNoTitle) {
652 SetDryRun(true);
Felipe Leme7447d7c2016-11-03 18:12:22 -0700653 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700654 EXPECT_THAT(out, IsEmpty());
655 EXPECT_THAT(err, IsEmpty());
656}
657
658TEST_F(DumpstateTest, RunCommandDryRunAlways) {
659 SetDryRun(true);
Felipe Leme7447d7c2016-11-03 18:12:22 -0700660 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(10).Always().Build()));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700661 EXPECT_THAT(out, StrEq("stdout\n"));
662 EXPECT_THAT(err, StrEq("stderr\n"));
663}
664
Felipe Lemefd8affa2016-09-30 17:38:57 -0700665TEST_F(DumpstateTest, RunCommandNotFound) {
666 EXPECT_NE(0, RunCommand("", {"/there/cannot/be/such/command"}));
667 EXPECT_THAT(out, StartsWith("*** command '/there/cannot/be/such/command' failed: exit code"));
668 EXPECT_THAT(err, StartsWith("execvp on command '/there/cannot/be/such/command' failed"));
669}
670
671TEST_F(DumpstateTest, RunCommandFails) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700672 EXPECT_EQ(42, RunCommand("", {kSimpleCommand, "--exit", "42"}));
673 EXPECT_THAT(out, StrEq("stdout\n*** command '" + kSimpleCommand +
Felipe Leme9a523ae2016-10-20 15:10:33 -0700674 " --exit 42' failed: exit code 42\n"));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700675 EXPECT_THAT(err, StrEq("stderr\n*** command '" + kSimpleCommand +
Felipe Leme9a523ae2016-10-20 15:10:33 -0700676 " --exit 42' failed: exit code 42\n"));
Felipe Lemefd8affa2016-09-30 17:38:57 -0700677}
678
679TEST_F(DumpstateTest, RunCommandCrashes) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700680 EXPECT_NE(0, RunCommand("", {kSimpleCommand, "--crash"}));
Felipe Lemefd8affa2016-09-30 17:38:57 -0700681 // We don't know the exit code, so check just the prefix.
682 EXPECT_THAT(
Felipe Leme7447d7c2016-11-03 18:12:22 -0700683 out, StartsWith("stdout\n*** command '" + kSimpleCommand + " --crash' failed: exit code"));
Felipe Lemefd8affa2016-09-30 17:38:57 -0700684 EXPECT_THAT(
Felipe Leme7447d7c2016-11-03 18:12:22 -0700685 err, StartsWith("stderr\n*** command '" + kSimpleCommand + " --crash' failed: exit code"));
Felipe Lemefd8affa2016-09-30 17:38:57 -0700686}
687
688TEST_F(DumpstateTest, RunCommandTimesout) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700689 EXPECT_EQ(-1, RunCommand("", {kSimpleCommand, "--sleep", "2"},
Felipe Lemefd8affa2016-09-30 17:38:57 -0700690 CommandOptions::WithTimeout(1).Build()));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700691 EXPECT_THAT(out, StartsWith("stdout line1\n*** command '" + kSimpleCommand +
Felipe Lemefd8affa2016-09-30 17:38:57 -0700692 " --sleep 2' timed out after 1"));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700693 EXPECT_THAT(err, StartsWith("sleeping for 2s\n*** command '" + kSimpleCommand +
Felipe Lemefd8affa2016-09-30 17:38:57 -0700694 " --sleep 2' timed out after 1"));
695}
696
697TEST_F(DumpstateTest, RunCommandIsKilled) {
698 CaptureStdout();
699 CaptureStderr();
700
701 std::thread t([=]() {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700702 EXPECT_EQ(SIGTERM, ds.RunCommand("", {kSimpleCommand, "--pid", "--sleep", "20"},
Felipe Lemefd8affa2016-09-30 17:38:57 -0700703 CommandOptions::WithTimeout(100).Always().Build()));
704 });
705
706 // Capture pid and pre-sleep output.
707 sleep(1); // Wait a little bit to make sure pid and 1st line were printed.
708 std::string err = GetCapturedStderr();
709 EXPECT_THAT(err, StrEq("sleeping for 20s\n"));
710
711 std::string out = GetCapturedStdout();
712 std::vector<std::string> lines = android::base::Split(out, "\n");
713 ASSERT_EQ(3, (int)lines.size()) << "Invalid lines before sleep: " << out;
714
715 int pid = atoi(lines[0].c_str());
716 EXPECT_THAT(lines[1], StrEq("stdout line1"));
717 EXPECT_THAT(lines[2], IsEmpty()); // \n
718
719 // Then kill the process.
720 CaptureStdout();
721 CaptureStderr();
722 ASSERT_EQ(0, kill(pid, SIGTERM)) << "failed to kill pid " << pid;
723 t.join();
724
725 // Finally, check output after murder.
726 out = GetCapturedStdout();
727 err = GetCapturedStderr();
728
Felipe Leme7447d7c2016-11-03 18:12:22 -0700729 EXPECT_THAT(out, StrEq("*** command '" + kSimpleCommand +
Felipe Lemefd8affa2016-09-30 17:38:57 -0700730 " --pid --sleep 20' failed: killed by signal 15\n"));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700731 EXPECT_THAT(err, StrEq("*** command '" + kSimpleCommand +
Felipe Lemefd8affa2016-09-30 17:38:57 -0700732 " --pid --sleep 20' failed: killed by signal 15\n"));
733}
734
Felipe Leme75876a22016-10-27 16:31:27 -0700735TEST_F(DumpstateTest, RunCommandProgress) {
736 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
737 ds.listener_ = listener;
Felipe Leme7447d7c2016-11-03 18:12:22 -0700738 SetProgress(0, 30);
Felipe Leme75876a22016-10-27 16:31:27 -0700739
Nandana Duttbabf6c72019-01-15 14:11:12 +0000740 EXPECT_CALL(*listener, onProgress(66)); // 20/30 %
Felipe Leme7447d7c2016-11-03 18:12:22 -0700741 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(20).Build()));
Abhijeet Kaured5d6a62019-10-07 15:02:05 +0100742 std::string progress_message = GetProgressMessage(20, 30);
Felipe Leme75876a22016-10-27 16:31:27 -0700743 EXPECT_THAT(out, StrEq("stdout\n"));
744 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
745
Nandana Dutt402a8392019-06-14 14:25:13 +0100746 EXPECT_CALL(*listener, onProgress(80)); // 24/30 %
747 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(4).Build()));
Abhijeet Kaured5d6a62019-10-07 15:02:05 +0100748 progress_message = GetProgressMessage(24, 30);
Felipe Leme75876a22016-10-27 16:31:27 -0700749 EXPECT_THAT(out, StrEq("stdout\n"));
750 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
751
752 // Make sure command ran while in dry_run is counted.
753 SetDryRun(true);
Nandana Dutt402a8392019-06-14 14:25:13 +0100754 EXPECT_CALL(*listener, onProgress(90)); // 27/30 %
755 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(3).Build()));
Abhijeet Kaured5d6a62019-10-07 15:02:05 +0100756 progress_message = GetProgressMessage(27, 30);
Felipe Leme75876a22016-10-27 16:31:27 -0700757 EXPECT_THAT(out, IsEmpty());
758 EXPECT_THAT(err, StrEq(progress_message));
759
Nandana Dutt402a8392019-06-14 14:25:13 +0100760 SetDryRun(false);
761 EXPECT_CALL(*listener, onProgress(96)); // 29/30 %
762 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(2).Build()));
Abhijeet Kaured5d6a62019-10-07 15:02:05 +0100763 progress_message = GetProgressMessage(29, 30);
Felipe Leme009ecbb2016-11-07 10:18:44 -0800764 EXPECT_THAT(out, StrEq("stdout\n"));
765 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
766
Nandana Dutt402a8392019-06-14 14:25:13 +0100767 EXPECT_CALL(*listener, onProgress(100)); // 30/30 %
Felipe Leme009ecbb2016-11-07 10:18:44 -0800768 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).Build()));
Abhijeet Kaured5d6a62019-10-07 15:02:05 +0100769 progress_message = GetProgressMessage(30, 30);
Felipe Leme009ecbb2016-11-07 10:18:44 -0800770 EXPECT_THAT(out, StrEq("stdout\n"));
771 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
772
773 ds.listener_.clear();
774}
775
Felipe Lemed80e6b62016-10-03 13:08:14 -0700776TEST_F(DumpstateTest, RunCommandDropRoot) {
Felipe Leme46b85da2016-11-21 17:40:45 -0800777 if (!IsStandalone()) {
778 // TODO: temporarily disabled because it might cause other tests to fail after dropping
779 // to Shell - need to refactor tests to avoid this problem)
780 MYLOGE("Skipping DumpstateTest.RunCommandDropRoot() on test suite\n")
781 return;
782 }
Felipe Lemed80e6b62016-10-03 13:08:14 -0700783 // First check root case - only available when running with 'adb root'.
784 uid_t uid = getuid();
785 if (uid == 0) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700786 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"}));
Felipe Lemed80e6b62016-10-03 13:08:14 -0700787 EXPECT_THAT(out, StrEq("0\nstdout\n"));
788 EXPECT_THAT(err, StrEq("stderr\n"));
789 return;
790 }
Felipe Leme7447d7c2016-11-03 18:12:22 -0700791 // Then run dropping root.
792 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
Felipe Lemed80e6b62016-10-03 13:08:14 -0700793 CommandOptions::WithTimeout(1).DropRoot().Build()));
794 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
Felipe Leme26c41572016-10-06 14:34:43 -0700795 EXPECT_THAT(err, StrEq("drop_root_user(): already running as Shell\nstderr\n"));
Felipe Lemed80e6b62016-10-03 13:08:14 -0700796}
797
798TEST_F(DumpstateTest, RunCommandAsRootUserBuild) {
Felipe Leme46b85da2016-11-21 17:40:45 -0800799 if (!IsStandalone()) {
800 // TODO: temporarily disabled because it might cause other tests to fail after dropping
801 // to Shell - need to refactor tests to avoid this problem)
802 MYLOGE("Skipping DumpstateTest.RunCommandAsRootUserBuild() on test suite\n")
803 return;
804 }
Felipe Lemef0292972016-11-22 13:57:05 -0800805 if (!PropertiesHelper::IsUserBuild()) {
Felipe Lemed80e6b62016-10-03 13:08:14 -0700806 // Emulates user build if necessarily.
807 SetBuildType("user");
808 }
809
810 DropRoot();
811
Felipe Leme7447d7c2016-11-03 18:12:22 -0700812 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).AsRoot().Build()));
Felipe Lemed80e6b62016-10-03 13:08:14 -0700813
814 // We don't know the exact path of su, so we just check for the 'root ...' commands
815 EXPECT_THAT(out, StartsWith("Skipping"));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700816 EXPECT_THAT(out, EndsWith("root " + kSimpleCommand + "' on user build.\n"));
Felipe Lemed80e6b62016-10-03 13:08:14 -0700817 EXPECT_THAT(err, IsEmpty());
818}
819
Felipe Leme46b85da2016-11-21 17:40:45 -0800820TEST_F(DumpstateTest, RunCommandAsRootNonUserBuild) {
821 if (!IsStandalone()) {
822 // TODO: temporarily disabled because it might cause other tests to fail after dropping
823 // to Shell - need to refactor tests to avoid this problem)
824 MYLOGE("Skipping DumpstateTest.RunCommandAsRootNonUserBuild() on test suite\n")
825 return;
826 }
Felipe Lemef0292972016-11-22 13:57:05 -0800827 if (PropertiesHelper::IsUserBuild()) {
Felipe Leme46b85da2016-11-21 17:40:45 -0800828 ALOGI("Skipping RunCommandAsRootNonUserBuild on user builds\n");
829 return;
830 }
831
832 DropRoot();
833
834 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
835 CommandOptions::WithTimeout(1).AsRoot().Build()));
836
837 EXPECT_THAT(out, StrEq("0\nstdout\n"));
838 EXPECT_THAT(err, StrEq("stderr\n"));
839}
840
Nandana Dutt4b392be2018-11-02 16:17:05 +0000841TEST_F(DumpstateTest, RunCommandAsRootNonUserBuild_withUnroot) {
842 if (!IsStandalone()) {
843 // TODO: temporarily disabled because it might cause other tests to fail after dropping
844 // to Shell - need to refactor tests to avoid this problem)
845 MYLOGE(
846 "Skipping DumpstateTest.RunCommandAsRootNonUserBuild_withUnroot() "
847 "on test suite\n")
848 return;
849 }
850 if (PropertiesHelper::IsUserBuild()) {
851 ALOGI("Skipping RunCommandAsRootNonUserBuild_withUnroot on user builds\n");
852 return;
853 }
854
855 // Same test as above, but with unroot property set, which will override su availability.
856 SetUnroot(true);
857 DropRoot();
858
859 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
860 CommandOptions::WithTimeout(1).AsRoot().Build()));
861
862 // AsRoot is ineffective.
863 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
864 EXPECT_THAT(err, StrEq("drop_root_user(): already running as Shell\nstderr\n"));
865}
866
Yifan Hong48e83a12017-10-03 14:10:07 -0700867TEST_F(DumpstateTest, RunCommandAsRootIfAvailableOnUserBuild) {
868 if (!IsStandalone()) {
869 // TODO: temporarily disabled because it might cause other tests to fail after dropping
870 // to Shell - need to refactor tests to avoid this problem)
871 MYLOGE("Skipping DumpstateTest.RunCommandAsRootIfAvailableOnUserBuild() on test suite\n")
872 return;
873 }
874 if (!PropertiesHelper::IsUserBuild()) {
875 // Emulates user build if necessarily.
876 SetBuildType("user");
877 }
878
879 DropRoot();
880
881 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
882 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
883
884 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
885 EXPECT_THAT(err, StrEq("stderr\n"));
886}
887
888TEST_F(DumpstateTest, RunCommandAsRootIfAvailableOnDebugBuild) {
889 if (!IsStandalone()) {
890 // TODO: temporarily disabled because it might cause other tests to fail after dropping
891 // to Shell - need to refactor tests to avoid this problem)
892 MYLOGE("Skipping DumpstateTest.RunCommandAsRootIfAvailableOnDebugBuild() on test suite\n")
893 return;
894 }
895 if (PropertiesHelper::IsUserBuild()) {
896 ALOGI("Skipping RunCommandAsRootNonUserBuild on user builds\n");
897 return;
898 }
899
900 DropRoot();
901
902 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
903 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
904
905 EXPECT_THAT(out, StrEq("0\nstdout\n"));
906 EXPECT_THAT(err, StrEq("stderr\n"));
907}
908
Nandana Dutt4b392be2018-11-02 16:17:05 +0000909TEST_F(DumpstateTest, RunCommandAsRootIfAvailableOnDebugBuild_withUnroot) {
910 if (!IsStandalone()) {
911 // TODO: temporarily disabled because it might cause other tests to fail after dropping
912 // to Shell - need to refactor tests to avoid this problem)
913 MYLOGE(
914 "Skipping DumpstateTest.RunCommandAsRootIfAvailableOnDebugBuild_withUnroot() "
915 "on test suite\n")
916 return;
917 }
918 if (PropertiesHelper::IsUserBuild()) {
919 ALOGI("Skipping RunCommandAsRootIfAvailableOnDebugBuild_withUnroot on user builds\n");
920 return;
921 }
922 // Same test as above, but with unroot property set, which will override su availability.
923 SetUnroot(true);
924
925 DropRoot();
926
927 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
928 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
929
930 // It's a userdebug build, so "su root" should be available, but unroot=true overrides it.
931 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
932 EXPECT_THAT(err, StrEq("stderr\n"));
933}
934
Felipe Lemecef02982016-10-03 17:22:22 -0700935TEST_F(DumpstateTest, DumpFileNotFoundNoTitle) {
936 EXPECT_EQ(-1, DumpFile("", "/I/cant/believe/I/exist"));
937 EXPECT_THAT(out,
938 StrEq("*** Error dumping /I/cant/believe/I/exist: No such file or directory\n"));
939 EXPECT_THAT(err, IsEmpty());
940}
941
942TEST_F(DumpstateTest, DumpFileNotFoundWithTitle) {
943 EXPECT_EQ(-1, DumpFile("Y U NO EXIST?", "/I/cant/believe/I/exist"));
944 EXPECT_THAT(err, IsEmpty());
Greg Kaiser3a811c12019-05-21 12:48:59 -0700945 // The duration may not get output, depending on how long it takes,
946 // so we just check the prefix.
Felipe Lemecef02982016-10-03 17:22:22 -0700947 EXPECT_THAT(out, StartsWith("*** Error dumping /I/cant/believe/I/exist (Y U NO EXIST?): No "
948 "such file or directory\n"));
Felipe Lemecef02982016-10-03 17:22:22 -0700949}
950
951TEST_F(DumpstateTest, DumpFileSingleLine) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700952 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -0700953 EXPECT_THAT(err, IsEmpty());
954 EXPECT_THAT(out, StrEq("I AM LINE1\n")); // dumpstate adds missing newline
955}
956
957TEST_F(DumpstateTest, DumpFileSingleLineWithNewLine) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700958 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line-with-newline.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -0700959 EXPECT_THAT(err, IsEmpty());
960 EXPECT_THAT(out, StrEq("I AM LINE1\n"));
961}
962
963TEST_F(DumpstateTest, DumpFileMultipleLines) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700964 EXPECT_EQ(0, DumpFile("", kTestDataPath + "multiple-lines.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -0700965 EXPECT_THAT(err, IsEmpty());
966 EXPECT_THAT(out, StrEq("I AM LINE1\nI AM LINE2\nI AM LINE3\n"));
967}
968
969TEST_F(DumpstateTest, DumpFileMultipleLinesWithNewLine) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700970 EXPECT_EQ(0, DumpFile("", kTestDataPath + "multiple-lines-with-newline.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -0700971 EXPECT_THAT(err, IsEmpty());
972 EXPECT_THAT(out, StrEq("I AM LINE1\nI AM LINE2\nI AM LINE3\n"));
973}
974
975TEST_F(DumpstateTest, DumpFileOnDryRunNoTitle) {
976 SetDryRun(true);
Felipe Leme7447d7c2016-11-03 18:12:22 -0700977 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -0700978 EXPECT_THAT(err, IsEmpty());
979 EXPECT_THAT(out, IsEmpty());
980}
981
982TEST_F(DumpstateTest, DumpFileOnDryRun) {
983 SetDryRun(true);
Felipe Leme7447d7c2016-11-03 18:12:22 -0700984 EXPECT_EQ(0, DumpFile("Might as well dump. Dump!", kTestDataPath + "single-line.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -0700985 EXPECT_THAT(err, IsEmpty());
Felipe Leme46b85da2016-11-21 17:40:45 -0800986 EXPECT_THAT(
987 out, StartsWith("------ Might as well dump. Dump! (" + kTestDataPath + "single-line.txt:"));
Nandana Dutt47527b52019-03-29 15:34:36 +0000988 EXPECT_THAT(out, HasSubstr("\n\t(skipped on dry run)\n"));
Felipe Lemecef02982016-10-03 17:22:22 -0700989}
990
Felipe Leme75876a22016-10-27 16:31:27 -0700991TEST_F(DumpstateTest, DumpFileUpdateProgress) {
992 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
993 ds.listener_ = listener;
Felipe Leme7447d7c2016-11-03 18:12:22 -0700994 SetProgress(0, 30);
Felipe Leme75876a22016-10-27 16:31:27 -0700995
Nandana Duttbabf6c72019-01-15 14:11:12 +0000996 EXPECT_CALL(*listener, onProgress(16)); // 5/30 %
Felipe Leme7447d7c2016-11-03 18:12:22 -0700997 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
Felipe Leme75876a22016-10-27 16:31:27 -0700998
Abhijeet Kaured5d6a62019-10-07 15:02:05 +0100999 std::string progress_message = GetProgressMessage(5, 30); // TODO: unhardcode WEIGHT_FILE (5)?
Felipe Leme75876a22016-10-27 16:31:27 -07001000 EXPECT_THAT(err, StrEq(progress_message));
1001 EXPECT_THAT(out, StrEq("I AM LINE1\n")); // dumpstate adds missing newline
1002
1003 ds.listener_.clear();
1004}
1005
Felipe Leme7447d7c2016-11-03 18:12:22 -07001006class DumpstateServiceTest : public DumpstateBaseTest {
Felipe Leme75876a22016-10-27 16:31:27 -07001007 public:
1008 DumpstateService dss;
1009};
1010
Felipe Leme7447d7c2016-11-03 18:12:22 -07001011class ProgressTest : public DumpstateBaseTest {
1012 public:
1013 Progress GetInstance(int32_t max, double growth_factor, const std::string& path = "") {
1014 return Progress(max, growth_factor, path);
1015 }
1016
1017 void AssertStats(const std::string& path, int32_t expected_runs, int32_t expected_average) {
1018 std::string expected_content =
1019 android::base::StringPrintf("%d %d\n", expected_runs, expected_average);
1020 std::string actual_content;
Felipe Leme46b85da2016-11-21 17:40:45 -08001021 ReadFileToString(path, &actual_content);
Felipe Leme7447d7c2016-11-03 18:12:22 -07001022 ASSERT_THAT(actual_content, StrEq(expected_content)) << "invalid stats on " << path;
1023 }
1024};
1025
1026TEST_F(ProgressTest, SimpleTest) {
1027 Progress progress;
1028 EXPECT_EQ(0, progress.Get());
1029 EXPECT_EQ(Progress::kDefaultMax, progress.GetInitialMax());
1030 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1031
1032 bool max_increased = progress.Inc(1);
1033 EXPECT_EQ(1, progress.Get());
1034 EXPECT_EQ(Progress::kDefaultMax, progress.GetInitialMax());
1035 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1036 EXPECT_FALSE(max_increased);
1037
1038 // Ignore negative increase.
1039 max_increased = progress.Inc(-1);
1040 EXPECT_EQ(1, progress.Get());
1041 EXPECT_EQ(Progress::kDefaultMax, progress.GetInitialMax());
1042 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1043 EXPECT_FALSE(max_increased);
1044}
1045
1046TEST_F(ProgressTest, MaxGrowsInsideNewRange) {
1047 Progress progress = GetInstance(10, 1.2); // 20% growth factor
1048 EXPECT_EQ(0, progress.Get());
1049 EXPECT_EQ(10, progress.GetInitialMax());
1050 EXPECT_EQ(10, progress.GetMax());
1051
1052 // No increase
1053 bool max_increased = progress.Inc(10);
1054 EXPECT_EQ(10, progress.Get());
1055 EXPECT_EQ(10, progress.GetMax());
1056 EXPECT_FALSE(max_increased);
1057
1058 // Increase, with new value < max*20%
1059 max_increased = progress.Inc(1);
1060 EXPECT_EQ(11, progress.Get());
1061 EXPECT_EQ(13, progress.GetMax()); // 11 average * 20% growth = 13.2 = 13
1062 EXPECT_TRUE(max_increased);
1063}
1064
1065TEST_F(ProgressTest, MaxGrowsOutsideNewRange) {
1066 Progress progress = GetInstance(10, 1.2); // 20% growth factor
1067 EXPECT_EQ(0, progress.Get());
1068 EXPECT_EQ(10, progress.GetInitialMax());
1069 EXPECT_EQ(10, progress.GetMax());
1070
1071 // No increase
1072 bool max_increased = progress.Inc(10);
1073 EXPECT_EQ(10, progress.Get());
1074 EXPECT_EQ(10, progress.GetMax());
1075 EXPECT_FALSE(max_increased);
1076
1077 // Increase, with new value > max*20%
1078 max_increased = progress.Inc(5);
1079 EXPECT_EQ(15, progress.Get());
1080 EXPECT_EQ(18, progress.GetMax()); // 15 average * 20% growth = 18
1081 EXPECT_TRUE(max_increased);
1082}
1083
1084TEST_F(ProgressTest, InvalidPath) {
1085 Progress progress("/devil/null");
1086 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1087}
1088
1089TEST_F(ProgressTest, EmptyFile) {
1090 Progress progress(CopyTextFileFixture("empty-file.txt"));
1091 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1092}
1093
1094TEST_F(ProgressTest, InvalidLine1stEntryNAN) {
1095 Progress progress(CopyTextFileFixture("stats-invalid-1st-NAN.txt"));
1096 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1097}
1098
1099TEST_F(ProgressTest, InvalidLine2ndEntryNAN) {
1100 Progress progress(CopyTextFileFixture("stats-invalid-2nd-NAN.txt"));
1101 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1102}
1103
1104TEST_F(ProgressTest, InvalidLineBothNAN) {
1105 Progress progress(CopyTextFileFixture("stats-invalid-both-NAN.txt"));
1106 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1107}
1108
1109TEST_F(ProgressTest, InvalidLine1stEntryNegative) {
1110 Progress progress(CopyTextFileFixture("stats-invalid-1st-negative.txt"));
1111 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1112}
1113
1114TEST_F(ProgressTest, InvalidLine2ndEntryNegative) {
1115 Progress progress(CopyTextFileFixture("stats-invalid-2nd-negative.txt"));
1116 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1117}
1118
1119TEST_F(ProgressTest, InvalidLine1stEntryTooBig) {
1120 Progress progress(CopyTextFileFixture("stats-invalid-1st-too-big.txt"));
1121 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1122}
1123
1124TEST_F(ProgressTest, InvalidLine2ndEntryTooBig) {
1125 Progress progress(CopyTextFileFixture("stats-invalid-2nd-too-big.txt"));
1126 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1127}
1128
1129// Tests stats are properly saved when the file does not exists.
1130TEST_F(ProgressTest, FirstTime) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001131 if (!IsStandalone()) {
1132 // TODO: temporarily disabled because it's failing when running as suite
1133 MYLOGE("Skipping ProgressTest.FirstTime() on test suite\n")
1134 return;
1135 }
1136
Felipe Leme7447d7c2016-11-03 18:12:22 -07001137 std::string path = kTestDataPath + "FirstTime.txt";
1138 android::base::RemoveFileIfExists(path);
1139
1140 Progress run1(path);
1141 EXPECT_EQ(0, run1.Get());
1142 EXPECT_EQ(Progress::kDefaultMax, run1.GetInitialMax());
1143 EXPECT_EQ(Progress::kDefaultMax, run1.GetMax());
1144
1145 bool max_increased = run1.Inc(20);
1146 EXPECT_EQ(20, run1.Get());
1147 EXPECT_EQ(Progress::kDefaultMax, run1.GetMax());
1148 EXPECT_FALSE(max_increased);
1149
1150 run1.Save();
1151 AssertStats(path, 1, 20);
1152}
1153
1154// Tests what happens when the persistent settings contains the average duration of 1 run.
1155// Data on file is 1 run and 109 average.
1156TEST_F(ProgressTest, SecondTime) {
1157 std::string path = CopyTextFileFixture("stats-one-run-no-newline.txt");
1158
1159 Progress run1 = GetInstance(-42, 1.2, path);
1160 EXPECT_EQ(0, run1.Get());
1161 EXPECT_EQ(10, run1.GetInitialMax());
1162 EXPECT_EQ(10, run1.GetMax());
1163
1164 bool max_increased = run1.Inc(20);
1165 EXPECT_EQ(20, run1.Get());
1166 EXPECT_EQ(24, run1.GetMax());
1167 EXPECT_TRUE(max_increased);
1168
1169 // Average now is 2 runs and (10 + 20)/ 2 = 15
1170 run1.Save();
1171 AssertStats(path, 2, 15);
1172
1173 Progress run2 = GetInstance(-42, 1.2, path);
1174 EXPECT_EQ(0, run2.Get());
1175 EXPECT_EQ(15, run2.GetInitialMax());
1176 EXPECT_EQ(15, run2.GetMax());
1177
1178 max_increased = run2.Inc(25);
1179 EXPECT_EQ(25, run2.Get());
1180 EXPECT_EQ(30, run2.GetMax());
1181 EXPECT_TRUE(max_increased);
1182
1183 // Average now is 3 runs and (15 * 2 + 25)/ 3 = 18.33 = 18
1184 run2.Save();
1185 AssertStats(path, 3, 18);
1186
1187 Progress run3 = GetInstance(-42, 1.2, path);
1188 EXPECT_EQ(0, run3.Get());
1189 EXPECT_EQ(18, run3.GetInitialMax());
1190 EXPECT_EQ(18, run3.GetMax());
1191
1192 // Make sure average decreases as well
1193 max_increased = run3.Inc(5);
1194 EXPECT_EQ(5, run3.Get());
1195 EXPECT_EQ(18, run3.GetMax());
1196 EXPECT_FALSE(max_increased);
1197
1198 // Average now is 4 runs and (18 * 3 + 5)/ 4 = 14.75 = 14
1199 run3.Save();
1200 AssertStats(path, 4, 14);
1201}
1202
1203// Tests what happens when the persistent settings contains the average duration of 2 runs.
1204// Data on file is 2 runs and 15 average.
1205TEST_F(ProgressTest, ThirdTime) {
1206 std::string path = CopyTextFileFixture("stats-two-runs.txt");
1207 AssertStats(path, 2, 15); // Sanity check
1208
1209 Progress run1 = GetInstance(-42, 1.2, path);
1210 EXPECT_EQ(0, run1.Get());
1211 EXPECT_EQ(15, run1.GetInitialMax());
1212 EXPECT_EQ(15, run1.GetMax());
1213
1214 bool max_increased = run1.Inc(20);
1215 EXPECT_EQ(20, run1.Get());
1216 EXPECT_EQ(24, run1.GetMax());
1217 EXPECT_TRUE(max_increased);
1218
1219 // Average now is 3 runs and (15 * 2 + 20)/ 3 = 16.66 = 16
1220 run1.Save();
1221 AssertStats(path, 3, 16);
1222}
1223
Felipe Leme46b85da2016-11-21 17:40:45 -08001224class DumpstateUtilTest : public DumpstateBaseTest {
1225 public:
1226 void SetUp() {
1227 DumpstateBaseTest::SetUp();
1228 SetDryRun(false);
1229 }
1230
Felipe Leme46b85da2016-11-21 17:40:45 -08001231 void CaptureFdOut() {
Felipe Lemef0292972016-11-22 13:57:05 -08001232 ReadFileToString(path_, &out);
Felipe Leme46b85da2016-11-21 17:40:45 -08001233 }
1234
1235 void CreateFd(const std::string& name) {
1236 path_ = kTestDataPath + name;
1237 MYLOGD("Creating fd for file %s\n", path_.c_str());
1238
1239 fd = TEMP_FAILURE_RETRY(open(path_.c_str(),
1240 O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW,
1241 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH));
1242 ASSERT_GE(fd, 0) << "could not create FD for path " << path_;
1243 }
1244
1245 // Runs a command into the `fd` and capture `stderr`.
Felipe Lemef0292972016-11-22 13:57:05 -08001246 int RunCommand(const std::string& title, const std::vector<std::string>& full_command,
Felipe Leme46b85da2016-11-21 17:40:45 -08001247 const CommandOptions& options = CommandOptions::DEFAULT) {
1248 CaptureStderr();
Felipe Lemef0292972016-11-22 13:57:05 -08001249 int status = RunCommandToFd(fd, title, full_command, options);
Felipe Leme46b85da2016-11-21 17:40:45 -08001250 close(fd);
1251
1252 CaptureFdOut();
1253 err = GetCapturedStderr();
1254 return status;
1255 }
1256
1257 // Dumps a file and into the `fd` and `stderr`.
Felipe Lemef0292972016-11-22 13:57:05 -08001258 int DumpFile(const std::string& title, const std::string& path) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001259 CaptureStderr();
Felipe Lemef0292972016-11-22 13:57:05 -08001260 int status = DumpFileToFd(fd, title, path);
Felipe Leme46b85da2016-11-21 17:40:45 -08001261 close(fd);
1262
1263 CaptureFdOut();
1264 err = GetCapturedStderr();
1265 return status;
1266 }
1267
1268 int fd;
1269
1270 // 'fd` output and `stderr` from the last command ran.
1271 std::string out, err;
1272
1273 private:
1274 std::string path_;
1275};
1276
1277TEST_F(DumpstateUtilTest, RunCommandNoArgs) {
Felipe Lemef0292972016-11-22 13:57:05 -08001278 CreateFd("RunCommandNoArgs.txt");
1279 EXPECT_EQ(-1, RunCommand("", {}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001280}
1281
Felipe Lemef0292972016-11-22 13:57:05 -08001282TEST_F(DumpstateUtilTest, RunCommandNoTitle) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001283 CreateFd("RunCommandWithNoArgs.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001284 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001285 EXPECT_THAT(out, StrEq("stdout\n"));
1286 EXPECT_THAT(err, StrEq("stderr\n"));
1287}
1288
Felipe Lemef0292972016-11-22 13:57:05 -08001289TEST_F(DumpstateUtilTest, RunCommandWithTitle) {
1290 CreateFd("RunCommandWithNoArgs.txt");
1291 EXPECT_EQ(0, RunCommand("I AM GROOT", {kSimpleCommand}));
1292 EXPECT_THAT(out, StrEq("------ I AM GROOT (" + kSimpleCommand + ") ------\nstdout\n"));
1293 EXPECT_THAT(err, StrEq("stderr\n"));
1294}
1295
Felipe Leme46b85da2016-11-21 17:40:45 -08001296TEST_F(DumpstateUtilTest, RunCommandWithOneArg) {
1297 CreateFd("RunCommandWithOneArg.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001298 EXPECT_EQ(0, RunCommand("", {kEchoCommand, "one"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001299 EXPECT_THAT(err, IsEmpty());
1300 EXPECT_THAT(out, StrEq("one\n"));
1301}
1302
1303TEST_F(DumpstateUtilTest, RunCommandWithMultipleArgs) {
1304 CreateFd("RunCommandWithMultipleArgs.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001305 EXPECT_EQ(0, RunCommand("", {kEchoCommand, "one", "is", "the", "loniest", "number"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001306 EXPECT_THAT(err, IsEmpty());
1307 EXPECT_THAT(out, StrEq("one is the loniest number\n"));
1308}
1309
1310TEST_F(DumpstateUtilTest, RunCommandWithLoggingMessage) {
1311 CreateFd("RunCommandWithLoggingMessage.txt");
1312 EXPECT_EQ(
Felipe Lemef0292972016-11-22 13:57:05 -08001313 0, RunCommand("", {kSimpleCommand},
Felipe Leme46b85da2016-11-21 17:40:45 -08001314 CommandOptions::WithTimeout(10).Log("COMMAND, Y U NO LOG FIRST?").Build()));
1315 EXPECT_THAT(out, StrEq("stdout\n"));
1316 EXPECT_THAT(err, StrEq("COMMAND, Y U NO LOG FIRST?stderr\n"));
1317}
1318
1319TEST_F(DumpstateUtilTest, RunCommandRedirectStderr) {
1320 CreateFd("RunCommandRedirectStderr.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001321 EXPECT_EQ(0, RunCommand("", {kSimpleCommand},
1322 CommandOptions::WithTimeout(10).RedirectStderr().Build()));
Felipe Leme46b85da2016-11-21 17:40:45 -08001323 EXPECT_THAT(out, IsEmpty());
1324 EXPECT_THAT(err, StrEq("stdout\nstderr\n"));
1325}
1326
1327TEST_F(DumpstateUtilTest, RunCommandDryRun) {
1328 CreateFd("RunCommandDryRun.txt");
1329 SetDryRun(true);
Felipe Lemef0292972016-11-22 13:57:05 -08001330 EXPECT_EQ(0, RunCommand("I AM GROOT", {kSimpleCommand}));
1331 EXPECT_THAT(out, StrEq(android::base::StringPrintf(
1332 "------ I AM GROOT (%s) ------\n\t(skipped on dry run)\n",
1333 kSimpleCommand.c_str())));
1334 EXPECT_THAT(err, IsEmpty());
1335}
1336
1337TEST_F(DumpstateUtilTest, RunCommandDryRunNoTitle) {
1338 CreateFd("RunCommandDryRun.txt");
1339 SetDryRun(true);
1340 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001341 EXPECT_THAT(
1342 out, StrEq(android::base::StringPrintf("%s: skipped on dry run\n", kSimpleCommand.c_str())));
1343 EXPECT_THAT(err, IsEmpty());
1344}
1345
1346TEST_F(DumpstateUtilTest, RunCommandDryRunAlways) {
1347 CreateFd("RunCommandDryRunAlways.txt");
1348 SetDryRun(true);
Felipe Lemef0292972016-11-22 13:57:05 -08001349 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(10).Always().Build()));
Felipe Leme46b85da2016-11-21 17:40:45 -08001350 EXPECT_THAT(out, StrEq("stdout\n"));
1351 EXPECT_THAT(err, StrEq("stderr\n"));
1352}
1353
1354TEST_F(DumpstateUtilTest, RunCommandNotFound) {
1355 CreateFd("RunCommandNotFound.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001356 EXPECT_NE(0, RunCommand("", {"/there/cannot/be/such/command"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001357 EXPECT_THAT(out, StartsWith("*** command '/there/cannot/be/such/command' failed: exit code"));
1358 EXPECT_THAT(err, StartsWith("execvp on command '/there/cannot/be/such/command' failed"));
1359}
1360
1361TEST_F(DumpstateUtilTest, RunCommandFails) {
1362 CreateFd("RunCommandFails.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001363 EXPECT_EQ(42, RunCommand("", {kSimpleCommand, "--exit", "42"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001364 EXPECT_THAT(out, StrEq("stdout\n*** command '" + kSimpleCommand +
1365 " --exit 42' failed: exit code 42\n"));
1366 EXPECT_THAT(err, StrEq("stderr\n*** command '" + kSimpleCommand +
1367 " --exit 42' failed: exit code 42\n"));
1368}
1369
1370TEST_F(DumpstateUtilTest, RunCommandCrashes) {
1371 CreateFd("RunCommandCrashes.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001372 EXPECT_NE(0, RunCommand("", {kSimpleCommand, "--crash"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001373 // We don't know the exit code, so check just the prefix.
1374 EXPECT_THAT(
1375 out, StartsWith("stdout\n*** command '" + kSimpleCommand + " --crash' failed: exit code"));
1376 EXPECT_THAT(
1377 err, StartsWith("stderr\n*** command '" + kSimpleCommand + " --crash' failed: exit code"));
1378}
1379
Vishnu Nair6921f802017-11-22 09:17:23 -08001380TEST_F(DumpstateUtilTest, RunCommandTimesoutWithSec) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001381 CreateFd("RunCommandTimesout.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001382 EXPECT_EQ(-1, RunCommand("", {kSimpleCommand, "--sleep", "2"},
1383 CommandOptions::WithTimeout(1).Build()));
Felipe Leme46b85da2016-11-21 17:40:45 -08001384 EXPECT_THAT(out, StartsWith("stdout line1\n*** command '" + kSimpleCommand +
1385 " --sleep 2' timed out after 1"));
1386 EXPECT_THAT(err, StartsWith("sleeping for 2s\n*** command '" + kSimpleCommand +
1387 " --sleep 2' timed out after 1"));
1388}
1389
Vishnu Nair6921f802017-11-22 09:17:23 -08001390TEST_F(DumpstateUtilTest, RunCommandTimesoutWithMsec) {
1391 CreateFd("RunCommandTimesout.txt");
1392 EXPECT_EQ(-1, RunCommand("", {kSimpleCommand, "--sleep", "2"},
1393 CommandOptions::WithTimeoutInMs(1000).Build()));
1394 EXPECT_THAT(out, StartsWith("stdout line1\n*** command '" + kSimpleCommand +
1395 " --sleep 2' timed out after 1"));
1396 EXPECT_THAT(err, StartsWith("sleeping for 2s\n*** command '" + kSimpleCommand +
1397 " --sleep 2' timed out after 1"));
1398}
1399
1400
Felipe Leme46b85da2016-11-21 17:40:45 -08001401TEST_F(DumpstateUtilTest, RunCommandIsKilled) {
1402 CreateFd("RunCommandIsKilled.txt");
1403 CaptureStderr();
1404
1405 std::thread t([=]() {
Felipe Lemef0292972016-11-22 13:57:05 -08001406 EXPECT_EQ(SIGTERM, RunCommandToFd(fd, "", {kSimpleCommand, "--pid", "--sleep", "20"},
Felipe Leme46b85da2016-11-21 17:40:45 -08001407 CommandOptions::WithTimeout(100).Always().Build()));
1408 });
1409
1410 // Capture pid and pre-sleep output.
1411 sleep(1); // Wait a little bit to make sure pid and 1st line were printed.
1412 std::string err = GetCapturedStderr();
1413 EXPECT_THAT(err, StrEq("sleeping for 20s\n"));
1414
1415 CaptureFdOut();
1416 std::vector<std::string> lines = android::base::Split(out, "\n");
1417 ASSERT_EQ(3, (int)lines.size()) << "Invalid lines before sleep: " << out;
1418
1419 int pid = atoi(lines[0].c_str());
1420 EXPECT_THAT(lines[1], StrEq("stdout line1"));
1421 EXPECT_THAT(lines[2], IsEmpty()); // \n
1422
1423 // Then kill the process.
1424 CaptureFdOut();
1425 CaptureStderr();
1426 ASSERT_EQ(0, kill(pid, SIGTERM)) << "failed to kill pid " << pid;
1427 t.join();
1428
1429 // Finally, check output after murder.
1430 CaptureFdOut();
1431 err = GetCapturedStderr();
1432
1433 // out starts with the pid, which is an unknown
1434 EXPECT_THAT(out, EndsWith("stdout line1\n*** command '" + kSimpleCommand +
1435 " --pid --sleep 20' failed: killed by signal 15\n"));
1436 EXPECT_THAT(err, StrEq("*** command '" + kSimpleCommand +
1437 " --pid --sleep 20' failed: killed by signal 15\n"));
1438}
1439
1440TEST_F(DumpstateUtilTest, RunCommandAsRootUserBuild) {
1441 if (!IsStandalone()) {
1442 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1443 // to Shell - need to refactor tests to avoid this problem)
1444 MYLOGE("Skipping DumpstateUtilTest.RunCommandAsRootUserBuild() on test suite\n")
1445 return;
1446 }
1447 CreateFd("RunCommandAsRootUserBuild.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001448 if (!PropertiesHelper::IsUserBuild()) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001449 // Emulates user build if necessarily.
1450 SetBuildType("user");
1451 }
1452
1453 DropRoot();
1454
Felipe Lemef0292972016-11-22 13:57:05 -08001455 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).AsRoot().Build()));
Felipe Leme46b85da2016-11-21 17:40:45 -08001456
1457 // We don't know the exact path of su, so we just check for the 'root ...' commands
1458 EXPECT_THAT(out, StartsWith("Skipping"));
1459 EXPECT_THAT(out, EndsWith("root " + kSimpleCommand + "' on user build.\n"));
1460 EXPECT_THAT(err, IsEmpty());
1461}
1462
1463TEST_F(DumpstateUtilTest, RunCommandAsRootNonUserBuild) {
1464 if (!IsStandalone()) {
1465 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1466 // to Shell - need to refactor tests to avoid this problem)
1467 MYLOGE("Skipping DumpstateUtilTest.RunCommandAsRootNonUserBuild() on test suite\n")
1468 return;
1469 }
1470 CreateFd("RunCommandAsRootNonUserBuild.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001471 if (PropertiesHelper::IsUserBuild()) {
Felipe Leme7447d7c2016-11-03 18:12:22 -07001472 ALOGI("Skipping RunCommandAsRootNonUserBuild on user builds\n");
1473 return;
1474 }
1475
1476 DropRoot();
1477
Felipe Lemef0292972016-11-22 13:57:05 -08001478 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
1479 CommandOptions::WithTimeout(1).AsRoot().Build()));
Felipe Leme7447d7c2016-11-03 18:12:22 -07001480
1481 EXPECT_THAT(out, StrEq("0\nstdout\n"));
1482 EXPECT_THAT(err, StrEq("stderr\n"));
1483}
Felipe Leme46b85da2016-11-21 17:40:45 -08001484
Yifan Hong48e83a12017-10-03 14:10:07 -07001485
1486TEST_F(DumpstateUtilTest, RunCommandAsRootIfAvailableOnUserBuild) {
1487 if (!IsStandalone()) {
1488 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1489 // to Shell - need to refactor tests to avoid this problem)
1490 MYLOGE("Skipping DumpstateUtilTest.RunCommandAsRootIfAvailableOnUserBuild() on test suite\n")
1491 return;
1492 }
1493 CreateFd("RunCommandAsRootIfAvailableOnUserBuild.txt");
1494 if (!PropertiesHelper::IsUserBuild()) {
1495 // Emulates user build if necessarily.
1496 SetBuildType("user");
1497 }
1498
1499 DropRoot();
1500
1501 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
1502 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
1503
1504 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
1505 EXPECT_THAT(err, StrEq("stderr\n"));
1506}
1507
1508TEST_F(DumpstateUtilTest, RunCommandAsRootIfAvailableOnDebugBuild) {
1509 if (!IsStandalone()) {
1510 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1511 // to Shell - need to refactor tests to avoid this problem)
1512 MYLOGE("Skipping DumpstateUtilTest.RunCommandAsRootIfAvailableOnDebugBuild() on test suite\n")
1513 return;
1514 }
1515 CreateFd("RunCommandAsRootIfAvailableOnDebugBuild.txt");
1516 if (PropertiesHelper::IsUserBuild()) {
1517 ALOGI("Skipping RunCommandAsRootNonUserBuild on user builds\n");
1518 return;
1519 }
1520
1521 DropRoot();
1522
1523 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
1524 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
1525
1526 EXPECT_THAT(out, StrEq("0\nstdout\n"));
1527 EXPECT_THAT(err, StrEq("stderr\n"));
1528}
1529
Felipe Leme46b85da2016-11-21 17:40:45 -08001530TEST_F(DumpstateUtilTest, RunCommandDropRoot) {
1531 if (!IsStandalone()) {
1532 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1533 // to Shell - need to refactor tests to avoid this problem)
1534 MYLOGE("Skipping DumpstateUtilTest.RunCommandDropRoot() on test suite\n")
1535 return;
1536 }
1537 CreateFd("RunCommandDropRoot.txt");
1538 // First check root case - only available when running with 'adb root'.
1539 uid_t uid = getuid();
1540 if (uid == 0) {
Felipe Lemef0292972016-11-22 13:57:05 -08001541 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001542 EXPECT_THAT(out, StrEq("0\nstdout\n"));
1543 EXPECT_THAT(err, StrEq("stderr\n"));
1544 return;
1545 }
1546 // Then run dropping root.
Felipe Lemef0292972016-11-22 13:57:05 -08001547 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
Felipe Leme46b85da2016-11-21 17:40:45 -08001548 CommandOptions::WithTimeout(1).DropRoot().Build()));
1549 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
1550 EXPECT_THAT(err, StrEq("drop_root_user(): already running as Shell\nstderr\n"));
1551}
1552
Felipe Lemef0292972016-11-22 13:57:05 -08001553TEST_F(DumpstateUtilTest, DumpFileNotFoundNoTitle) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001554 CreateFd("DumpFileNotFound.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001555 EXPECT_EQ(-1, DumpFile("", "/I/cant/believe/I/exist"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001556 EXPECT_THAT(out,
1557 StrEq("*** Error dumping /I/cant/believe/I/exist: No such file or directory\n"));
1558 EXPECT_THAT(err, IsEmpty());
1559}
1560
Felipe Lemef0292972016-11-22 13:57:05 -08001561TEST_F(DumpstateUtilTest, DumpFileNotFoundWithTitle) {
1562 CreateFd("DumpFileNotFound.txt");
1563 EXPECT_EQ(-1, DumpFile("Y U NO EXIST?", "/I/cant/believe/I/exist"));
1564 EXPECT_THAT(out, StrEq("*** Error dumping /I/cant/believe/I/exist (Y U NO EXIST?): No such "
1565 "file or directory\n"));
1566 EXPECT_THAT(err, IsEmpty());
1567}
1568
Felipe Leme46b85da2016-11-21 17:40:45 -08001569TEST_F(DumpstateUtilTest, DumpFileSingleLine) {
1570 CreateFd("DumpFileSingleLine.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001571 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001572 EXPECT_THAT(err, IsEmpty());
1573 EXPECT_THAT(out, StrEq("I AM LINE1\n")); // dumpstate adds missing newline
1574}
1575
1576TEST_F(DumpstateUtilTest, DumpFileSingleLineWithNewLine) {
1577 CreateFd("DumpFileSingleLineWithNewLine.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001578 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line-with-newline.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001579 EXPECT_THAT(err, IsEmpty());
1580 EXPECT_THAT(out, StrEq("I AM LINE1\n"));
1581}
1582
1583TEST_F(DumpstateUtilTest, DumpFileMultipleLines) {
1584 CreateFd("DumpFileMultipleLines.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001585 EXPECT_EQ(0, DumpFile("", kTestDataPath + "multiple-lines.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001586 EXPECT_THAT(err, IsEmpty());
1587 EXPECT_THAT(out, StrEq("I AM LINE1\nI AM LINE2\nI AM LINE3\n"));
1588}
1589
1590TEST_F(DumpstateUtilTest, DumpFileMultipleLinesWithNewLine) {
1591 CreateFd("DumpFileMultipleLinesWithNewLine.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001592 EXPECT_EQ(0, DumpFile("", kTestDataPath + "multiple-lines-with-newline.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001593 EXPECT_THAT(err, IsEmpty());
1594 EXPECT_THAT(out, StrEq("I AM LINE1\nI AM LINE2\nI AM LINE3\n"));
1595}
1596
Felipe Lemef0292972016-11-22 13:57:05 -08001597TEST_F(DumpstateUtilTest, DumpFileOnDryRunNoTitle) {
1598 CreateFd("DumpFileOnDryRun.txt");
1599 SetDryRun(true);
1600 std::string path = kTestDataPath + "single-line.txt";
1601 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
1602 EXPECT_THAT(err, IsEmpty());
1603 EXPECT_THAT(out, StrEq(path + ": skipped on dry run\n"));
1604}
1605
Felipe Leme46b85da2016-11-21 17:40:45 -08001606TEST_F(DumpstateUtilTest, DumpFileOnDryRun) {
1607 CreateFd("DumpFileOnDryRun.txt");
1608 SetDryRun(true);
1609 std::string path = kTestDataPath + "single-line.txt";
Felipe Lemef0292972016-11-22 13:57:05 -08001610 EXPECT_EQ(0, DumpFile("Might as well dump. Dump!", kTestDataPath + "single-line.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001611 EXPECT_THAT(err, IsEmpty());
Felipe Lemef0292972016-11-22 13:57:05 -08001612 EXPECT_THAT(
1613 out, StartsWith("------ Might as well dump. Dump! (" + kTestDataPath + "single-line.txt:"));
1614 EXPECT_THAT(out, EndsWith("skipped on dry run\n"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001615}
Ecco Park61ffcf72016-10-27 15:46:26 -07001616
Felipe Leme47e9be22016-12-21 15:37:07 -08001617} // namespace dumpstate
1618} // namespace os
1619} // namespace android