blob: 7078521b52eeadcc3d472b9e1b8d3642dcb8896b [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 Changc490e662020-04-11 18:14:09 +080069 MOCK_METHOD1(onUiIntensiveBugreportDumpsFinished,
70 binder::Status(const android::String16& callingpackage));
Felipe Leme75876a22016-10-27 16:31:27 -070071
72 protected:
73 MOCK_METHOD0(onAsBinder, IBinder*());
74};
75
Felipe Leme46b85da2016-11-21 17:40:45 -080076static int calls_;
77
Felipe Leme7447d7c2016-11-03 18:12:22 -070078// Base class for all tests in this file
79class DumpstateBaseTest : public Test {
Felipe Leme46b85da2016-11-21 17:40:45 -080080 public:
81 virtual void SetUp() override {
82 calls_++;
Felipe Lemef0292972016-11-22 13:57:05 -080083 SetDryRun(false);
Felipe Leme46b85da2016-11-21 17:40:45 -080084 }
85
Felipe Lemef0292972016-11-22 13:57:05 -080086 void SetDryRun(bool dry_run) const {
87 PropertiesHelper::dry_run_ = dry_run;
88 }
89
90 void SetBuildType(const std::string& build_type) const {
91 PropertiesHelper::build_type_ = build_type;
92 }
93
Nandana Dutt4b392be2018-11-02 16:17:05 +000094 void SetUnroot(bool unroot) const {
95 PropertiesHelper::unroot_ = unroot;
96 }
97
Felipe Lemef0292972016-11-22 13:57:05 -080098 bool IsStandalone() const {
Felipe Leme46b85da2016-11-21 17:40:45 -080099 return calls_ == 1;
100 }
101
Felipe Lemef0292972016-11-22 13:57:05 -0800102 void DropRoot() const {
103 DropRootUser();
Felipe Leme46b85da2016-11-21 17:40:45 -0800104 uid_t uid = getuid();
105 ASSERT_EQ(2000, (int)uid);
106 }
107
Felipe Leme7447d7c2016-11-03 18:12:22 -0700108 protected:
109 const std::string kTestPath = dirname(android::base::GetExecutablePath().c_str());
Dan Shie177e8e2019-06-20 11:08:14 -0700110 const std::string kTestDataPath = kTestPath + "/tests/testdata/";
111 const std::string kSimpleCommand = kTestPath + "/dumpstate_test_fixture";
Felipe Leme7447d7c2016-11-03 18:12:22 -0700112 const std::string kEchoCommand = "/system/bin/echo";
113
114 /*
115 * Copies a text file fixture to a temporary file, returning it's path.
116 *
117 * Useful in cases where the test case changes the content of the tile.
118 */
119 std::string CopyTextFileFixture(const std::string& relative_name) {
120 std::string from = kTestDataPath + relative_name;
121 // Not using TemporaryFile because it's deleted at the end, and it's useful to keep it
122 // around for poking when the test fails.
123 std::string to = kTestDataPath + relative_name + ".tmp";
124 ALOGD("CopyTextFileFixture: from %s to %s\n", from.c_str(), to.c_str());
125 android::base::RemoveFileIfExists(to);
126 CopyTextFile(from, to);
127 return to.c_str();
128 }
129
Felipe Leme46b85da2016-11-21 17:40:45 -0800130 // Need functions that returns void to use assertions -
Felipe Leme7447d7c2016-11-03 18:12:22 -0700131 // https://github.com/google/googletest/blob/master/googletest/docs/AdvancedGuide.md#assertion-placement
Felipe Leme46b85da2016-11-21 17:40:45 -0800132 void ReadFileToString(const std::string& path, std::string* content) {
133 ASSERT_TRUE(android::base::ReadFileToString(path, content))
134 << "could not read contents from " << path;
135 }
136 void WriteStringToFile(const std::string& content, const std::string& path) {
137 ASSERT_TRUE(android::base::WriteStringToFile(content, path))
138 << "could not write contents to " << path;
139 }
140
141 private:
Felipe Leme7447d7c2016-11-03 18:12:22 -0700142 void CopyTextFile(const std::string& from, const std::string& to) {
143 std::string content;
Felipe Leme46b85da2016-11-21 17:40:45 -0800144 ReadFileToString(from, &content);
145 WriteStringToFile(content, to);
Felipe Leme7447d7c2016-11-03 18:12:22 -0700146 }
147};
148
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100149class DumpOptionsTest : public Test {
150 public:
151 virtual ~DumpOptionsTest() {
152 }
153 virtual void SetUp() {
154 options_ = Dumpstate::DumpOptions();
155 }
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000156 void TearDown() {
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000157 }
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100158 Dumpstate::DumpOptions options_;
Abhijeet Kaure370d682019-10-01 16:49:30 +0100159 android::base::unique_fd fd;
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100160};
161
162TEST_F(DumpOptionsTest, InitializeNone) {
163 // clang-format off
164 char* argv[] = {
165 const_cast<char*>("dumpstate")
166 };
167 // clang-format on
168
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100169 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
170
171 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
Nandana Dutt58d72e22018-11-16 10:30:48 +0000172
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100173 EXPECT_FALSE(options_.do_add_date);
174 EXPECT_FALSE(options_.do_zip_file);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100175 EXPECT_FALSE(options_.use_socket);
176 EXPECT_FALSE(options_.use_control_socket);
177 EXPECT_FALSE(options_.show_header_only);
178 EXPECT_TRUE(options_.do_vibrate);
Paul Chang0d2aad72020-02-13 20:04:03 +0800179 EXPECT_FALSE(options_.do_screenshot);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100180 EXPECT_FALSE(options_.do_progress_updates);
181 EXPECT_FALSE(options_.is_remote_mode);
mhasankf56bbb22020-05-26 18:02:39 -0700182 EXPECT_FALSE(options_.arc_only);
Hunter Knepshield8540faf2020-02-04 19:47:20 -0800183 EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::DEFAULT);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000184}
185
186TEST_F(DumpOptionsTest, InitializeAdbBugreport) {
187 // clang-format off
188 char* argv[] = {
189 const_cast<char*>("dumpstatez"),
190 const_cast<char*>("-S"),
191 const_cast<char*>("-d"),
192 const_cast<char*>("-z"),
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000193 };
194 // clang-format on
195
196 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
197
198 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
199 EXPECT_TRUE(options_.do_add_date);
200 EXPECT_TRUE(options_.do_zip_file);
201 EXPECT_TRUE(options_.use_control_socket);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000202
203 // Other options retain default values
204 EXPECT_TRUE(options_.do_vibrate);
205 EXPECT_FALSE(options_.show_header_only);
Paul Chang0d2aad72020-02-13 20:04:03 +0800206 EXPECT_FALSE(options_.do_screenshot);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000207 EXPECT_FALSE(options_.do_progress_updates);
208 EXPECT_FALSE(options_.is_remote_mode);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000209 EXPECT_FALSE(options_.use_socket);
mhasankf56bbb22020-05-26 18:02:39 -0700210 EXPECT_FALSE(options_.arc_only);
Hunter Knepshield8540faf2020-02-04 19:47:20 -0800211 EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::DEFAULT);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000212}
213
214TEST_F(DumpOptionsTest, InitializeAdbShellBugreport) {
215 // clang-format off
216 char* argv[] = {
217 const_cast<char*>("dumpstate"),
218 const_cast<char*>("-s"),
219 };
220 // clang-format on
221
222 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
223
224 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
225 EXPECT_TRUE(options_.use_socket);
226
227 // Other options retain default values
228 EXPECT_TRUE(options_.do_vibrate);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000229 EXPECT_FALSE(options_.do_add_date);
230 EXPECT_FALSE(options_.do_zip_file);
231 EXPECT_FALSE(options_.use_control_socket);
232 EXPECT_FALSE(options_.show_header_only);
Paul Chang0d2aad72020-02-13 20:04:03 +0800233 EXPECT_FALSE(options_.do_screenshot);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000234 EXPECT_FALSE(options_.do_progress_updates);
235 EXPECT_FALSE(options_.is_remote_mode);
mhasankf56bbb22020-05-26 18:02:39 -0700236 EXPECT_FALSE(options_.arc_only);
Hunter Knepshield8540faf2020-02-04 19:47:20 -0800237 EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::DEFAULT);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000238}
239
240TEST_F(DumpOptionsTest, InitializeFullBugReport) {
Paul Changf59c2b72020-03-10 02:08:55 +0800241 options_.Initialize(Dumpstate::BugreportMode::BUGREPORT_FULL, fd, fd, true);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000242 EXPECT_TRUE(options_.do_add_date);
Paul Chang0d2aad72020-02-13 20:04:03 +0800243 EXPECT_TRUE(options_.do_screenshot);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000244 EXPECT_TRUE(options_.do_zip_file);
Hunter Knepshield8540faf2020-02-04 19:47:20 -0800245 EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::FULL);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000246
247 // Other options retain default values
248 EXPECT_TRUE(options_.do_vibrate);
249 EXPECT_FALSE(options_.use_control_socket);
250 EXPECT_FALSE(options_.show_header_only);
251 EXPECT_FALSE(options_.do_progress_updates);
252 EXPECT_FALSE(options_.is_remote_mode);
253 EXPECT_FALSE(options_.use_socket);
254 EXPECT_FALSE(options_.do_start_service);
mhasankf56bbb22020-05-26 18:02:39 -0700255 EXPECT_FALSE(options_.arc_only);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000256}
257
258TEST_F(DumpOptionsTest, InitializeInteractiveBugReport) {
Paul Changf59c2b72020-03-10 02:08:55 +0800259 options_.Initialize(Dumpstate::BugreportMode::BUGREPORT_INTERACTIVE, fd, fd, true);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000260 EXPECT_TRUE(options_.do_add_date);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000261 EXPECT_TRUE(options_.do_zip_file);
262 EXPECT_TRUE(options_.do_progress_updates);
263 EXPECT_TRUE(options_.do_start_service);
Paul Chang0d2aad72020-02-13 20:04:03 +0800264 EXPECT_TRUE(options_.do_screenshot);
Hunter Knepshield8540faf2020-02-04 19:47:20 -0800265 EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::INTERACTIVE);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000266
267 // Other options retain default values
268 EXPECT_TRUE(options_.do_vibrate);
269 EXPECT_FALSE(options_.use_control_socket);
270 EXPECT_FALSE(options_.show_header_only);
271 EXPECT_FALSE(options_.is_remote_mode);
272 EXPECT_FALSE(options_.use_socket);
mhasankf56bbb22020-05-26 18:02:39 -0700273 EXPECT_FALSE(options_.arc_only);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000274}
275
276TEST_F(DumpOptionsTest, InitializeRemoteBugReport) {
Paul Changf59c2b72020-03-10 02:08:55 +0800277 options_.Initialize(Dumpstate::BugreportMode::BUGREPORT_REMOTE, fd, fd, false);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000278 EXPECT_TRUE(options_.do_add_date);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000279 EXPECT_TRUE(options_.do_zip_file);
280 EXPECT_TRUE(options_.is_remote_mode);
281 EXPECT_FALSE(options_.do_vibrate);
Paul Chang0d2aad72020-02-13 20:04:03 +0800282 EXPECT_FALSE(options_.do_screenshot);
Hunter Knepshield8540faf2020-02-04 19:47:20 -0800283 EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::REMOTE);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000284
285 // Other options retain default values
286 EXPECT_FALSE(options_.use_control_socket);
287 EXPECT_FALSE(options_.show_header_only);
288 EXPECT_FALSE(options_.do_progress_updates);
289 EXPECT_FALSE(options_.use_socket);
mhasankf56bbb22020-05-26 18:02:39 -0700290 EXPECT_FALSE(options_.arc_only);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000291}
292
293TEST_F(DumpOptionsTest, InitializeWearBugReport) {
Paul Changf59c2b72020-03-10 02:08:55 +0800294 options_.Initialize(Dumpstate::BugreportMode::BUGREPORT_WEAR, fd, fd, true);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000295 EXPECT_TRUE(options_.do_add_date);
Paul Chang0d2aad72020-02-13 20:04:03 +0800296 EXPECT_TRUE(options_.do_screenshot);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000297 EXPECT_TRUE(options_.do_zip_file);
298 EXPECT_TRUE(options_.do_progress_updates);
299 EXPECT_TRUE(options_.do_start_service);
Hunter Knepshield8540faf2020-02-04 19:47:20 -0800300 EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::WEAR);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000301
302 // Other options retain default values
303 EXPECT_TRUE(options_.do_vibrate);
304 EXPECT_FALSE(options_.use_control_socket);
305 EXPECT_FALSE(options_.show_header_only);
306 EXPECT_FALSE(options_.is_remote_mode);
307 EXPECT_FALSE(options_.use_socket);
mhasankf56bbb22020-05-26 18:02:39 -0700308 EXPECT_FALSE(options_.arc_only);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000309}
310
311TEST_F(DumpOptionsTest, InitializeTelephonyBugReport) {
Paul Changf59c2b72020-03-10 02:08:55 +0800312 options_.Initialize(Dumpstate::BugreportMode::BUGREPORT_TELEPHONY, fd, fd, false);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000313 EXPECT_TRUE(options_.do_add_date);
Paul Chang0d2aad72020-02-13 20:04:03 +0800314 EXPECT_FALSE(options_.do_screenshot);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000315 EXPECT_TRUE(options_.do_zip_file);
316 EXPECT_TRUE(options_.telephony_only);
Hunter Knepshield820f9bc2020-02-05 20:10:53 -0800317 EXPECT_TRUE(options_.do_progress_updates);
Hunter Knepshield8540faf2020-02-04 19:47:20 -0800318 EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::CONNECTIVITY);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000319
320 // Other options retain default values
321 EXPECT_TRUE(options_.do_vibrate);
322 EXPECT_FALSE(options_.use_control_socket);
323 EXPECT_FALSE(options_.show_header_only);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000324 EXPECT_FALSE(options_.is_remote_mode);
325 EXPECT_FALSE(options_.use_socket);
mhasankf56bbb22020-05-26 18:02:39 -0700326 EXPECT_FALSE(options_.arc_only);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000327}
328
329TEST_F(DumpOptionsTest, InitializeWifiBugReport) {
Paul Changf59c2b72020-03-10 02:08:55 +0800330 options_.Initialize(Dumpstate::BugreportMode::BUGREPORT_WIFI, fd, fd, false);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000331 EXPECT_TRUE(options_.do_add_date);
Paul Chang0d2aad72020-02-13 20:04:03 +0800332 EXPECT_FALSE(options_.do_screenshot);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000333 EXPECT_TRUE(options_.do_zip_file);
334 EXPECT_TRUE(options_.wifi_only);
Hunter Knepshield8540faf2020-02-04 19:47:20 -0800335 EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::WIFI);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000336
337 // Other options retain default values
338 EXPECT_TRUE(options_.do_vibrate);
339 EXPECT_FALSE(options_.use_control_socket);
340 EXPECT_FALSE(options_.show_header_only);
341 EXPECT_FALSE(options_.do_progress_updates);
342 EXPECT_FALSE(options_.is_remote_mode);
343 EXPECT_FALSE(options_.use_socket);
mhasankf56bbb22020-05-26 18:02:39 -0700344 EXPECT_FALSE(options_.arc_only);
345}
346
347TEST_F(DumpOptionsTest, InitializeArcOnlyBugreport) {
348 // clang-format off
349 char* argv[] = {
350 const_cast<char*>("dumpstatez"),
351 const_cast<char*>("-S"),
352 const_cast<char*>("-d"),
353 const_cast<char*>("-z"),
354 const_cast<char*>("-q"),
355 const_cast<char*>("-A")
356 };
357 // clang-format on
358
359 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
360
361 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
362 EXPECT_TRUE(options_.do_add_date);
363 EXPECT_TRUE(options_.do_zip_file);
364 EXPECT_TRUE(options_.use_control_socket);
365 EXPECT_FALSE(options_.do_vibrate);
366 EXPECT_TRUE(options_.arc_only);
367
368 // Other options retain default values
369 EXPECT_FALSE(options_.show_header_only);
370 EXPECT_FALSE(options_.do_screenshot);
371 EXPECT_FALSE(options_.do_progress_updates);
372 EXPECT_FALSE(options_.is_remote_mode);
373 EXPECT_FALSE(options_.use_socket);
374 EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::DEFAULT);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000375}
376
377TEST_F(DumpOptionsTest, InitializeDefaultBugReport) {
378 // default: commandline options are not overridden
379 // clang-format off
380 char* argv[] = {
381 const_cast<char*>("bugreport"),
382 const_cast<char*>("-d"),
383 const_cast<char*>("-p"),
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000384 const_cast<char*>("-z"),
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000385 };
386 // clang-format on
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000387 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
388
389 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
390 EXPECT_TRUE(options_.do_add_date);
Paul Chang0d2aad72020-02-13 20:04:03 +0800391 EXPECT_TRUE(options_.do_screenshot);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000392 EXPECT_TRUE(options_.do_zip_file);
Hunter Knepshield8540faf2020-02-04 19:47:20 -0800393 EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::DEFAULT);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000394
395 // Other options retain default values
396 EXPECT_TRUE(options_.do_vibrate);
397 EXPECT_FALSE(options_.use_control_socket);
398 EXPECT_FALSE(options_.show_header_only);
399 EXPECT_FALSE(options_.do_progress_updates);
400 EXPECT_FALSE(options_.is_remote_mode);
401 EXPECT_FALSE(options_.use_socket);
402 EXPECT_FALSE(options_.wifi_only);
mhasankf56bbb22020-05-26 18:02:39 -0700403 EXPECT_FALSE(options_.arc_only);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100404}
405
406TEST_F(DumpOptionsTest, InitializePartial1) {
407 // clang-format off
408 char* argv[] = {
409 const_cast<char*>("dumpstate"),
410 const_cast<char*>("-d"),
411 const_cast<char*>("-z"),
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100412 const_cast<char*>("-s"),
413 const_cast<char*>("-S"),
414
415 };
416 // clang-format on
417
418 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
419
420 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
421 EXPECT_TRUE(options_.do_add_date);
422 EXPECT_TRUE(options_.do_zip_file);
423 // TODO: Maybe we should trim the filename
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100424 EXPECT_TRUE(options_.use_socket);
425 EXPECT_TRUE(options_.use_control_socket);
426
427 // Other options retain default values
428 EXPECT_FALSE(options_.show_header_only);
429 EXPECT_TRUE(options_.do_vibrate);
Paul Chang0d2aad72020-02-13 20:04:03 +0800430 EXPECT_FALSE(options_.do_screenshot);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100431 EXPECT_FALSE(options_.do_progress_updates);
432 EXPECT_FALSE(options_.is_remote_mode);
mhasankf56bbb22020-05-26 18:02:39 -0700433 EXPECT_FALSE(options_.arc_only);
Hunter Knepshield8540faf2020-02-04 19:47:20 -0800434 EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::DEFAULT);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100435}
436
437TEST_F(DumpOptionsTest, InitializePartial2) {
438 // clang-format off
439 char* argv[] = {
440 const_cast<char*>("dumpstate"),
441 const_cast<char*>("-v"),
442 const_cast<char*>("-q"),
443 const_cast<char*>("-p"),
444 const_cast<char*>("-P"),
445 const_cast<char*>("-R"),
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100446 };
447 // clang-format on
448
449 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
450
451 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
452 EXPECT_TRUE(options_.show_header_only);
453 EXPECT_FALSE(options_.do_vibrate);
Paul Chang0d2aad72020-02-13 20:04:03 +0800454 EXPECT_TRUE(options_.do_screenshot);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100455 EXPECT_TRUE(options_.do_progress_updates);
456 EXPECT_TRUE(options_.is_remote_mode);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100457
458 // Other options retain default values
459 EXPECT_FALSE(options_.do_add_date);
460 EXPECT_FALSE(options_.do_zip_file);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100461 EXPECT_FALSE(options_.use_socket);
462 EXPECT_FALSE(options_.use_control_socket);
mhasankf56bbb22020-05-26 18:02:39 -0700463 EXPECT_FALSE(options_.arc_only);
Hunter Knepshield8540faf2020-02-04 19:47:20 -0800464 EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::DEFAULT);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100465}
466
467TEST_F(DumpOptionsTest, InitializeHelp) {
468 // clang-format off
469 char* argv[] = {
470 const_cast<char*>("dumpstate"),
471 const_cast<char*>("-h")
472 };
473 // clang-format on
474
475 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
476
477 // -h is for help.
478 EXPECT_EQ(status, Dumpstate::RunStatus::HELP);
479}
480
481TEST_F(DumpOptionsTest, InitializeUnknown) {
482 // clang-format off
483 char* argv[] = {
484 const_cast<char*>("dumpstate"),
485 const_cast<char*>("-u") // unknown flag
486 };
487 // clang-format on
488
489 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
490
491 // -u is unknown.
492 EXPECT_EQ(status, Dumpstate::RunStatus::INVALID_INPUT);
493}
494
495TEST_F(DumpOptionsTest, ValidateOptionsNeedOutfile1) {
496 options_.do_zip_file = true;
Nandana Dutt9a76d202019-01-21 15:56:48 +0000497 // Writing to socket = !writing to file.
498 options_.use_socket = true;
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100499 EXPECT_FALSE(options_.ValidateOptions());
Nandana Dutt9a76d202019-01-21 15:56:48 +0000500
501 options_.use_socket = false;
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100502 EXPECT_TRUE(options_.ValidateOptions());
503}
504
505TEST_F(DumpOptionsTest, ValidateOptionsNeedOutfile2) {
Abhijeet Kaure370d682019-10-01 16:49:30 +0100506 options_.do_progress_updates = true;
Nandana Dutt9a76d202019-01-21 15:56:48 +0000507 // Writing to socket = !writing to file.
508 options_.use_socket = true;
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100509 EXPECT_FALSE(options_.ValidateOptions());
Nandana Dutt9a76d202019-01-21 15:56:48 +0000510
511 options_.use_socket = false;
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100512 EXPECT_TRUE(options_.ValidateOptions());
513}
514
515TEST_F(DumpOptionsTest, ValidateOptionsNeedZipfile) {
516 options_.use_control_socket = true;
517 EXPECT_FALSE(options_.ValidateOptions());
518
519 options_.do_zip_file = true;
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100520 EXPECT_TRUE(options_.ValidateOptions());
521}
522
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100523TEST_F(DumpOptionsTest, ValidateOptionsRemoteMode) {
524 options_.is_remote_mode = true;
525 EXPECT_FALSE(options_.ValidateOptions());
526
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100527 options_.do_zip_file = true;
528 options_.do_add_date = true;
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100529 EXPECT_TRUE(options_.ValidateOptions());
530}
531
Felipe Leme7447d7c2016-11-03 18:12:22 -0700532class DumpstateTest : public DumpstateBaseTest {
Felipe Leme4c2d6632016-09-28 14:32:00 -0700533 public:
534 void SetUp() {
Felipe Leme46b85da2016-11-21 17:40:45 -0800535 DumpstateBaseTest::SetUp();
Felipe Leme4c2d6632016-09-28 14:32:00 -0700536 SetDryRun(false);
Felipe Lemed80e6b62016-10-03 13:08:14 -0700537 SetBuildType(android::base::GetProperty("ro.build.type", "(unknown)"));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700538 ds.progress_.reset(new Progress());
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100539 ds.options_.reset(new Dumpstate::DumpOptions());
Felipe Leme4c2d6632016-09-28 14:32:00 -0700540 }
541
542 // Runs a command and capture `stdout` and `stderr`.
Felipe Leme9a523ae2016-10-20 15:10:33 -0700543 int RunCommand(const std::string& title, const std::vector<std::string>& full_command,
Felipe Leme4c2d6632016-09-28 14:32:00 -0700544 const CommandOptions& options = CommandOptions::DEFAULT) {
545 CaptureStdout();
546 CaptureStderr();
Felipe Leme9a523ae2016-10-20 15:10:33 -0700547 int status = ds.RunCommand(title, full_command, options);
Felipe Leme4c2d6632016-09-28 14:32:00 -0700548 out = GetCapturedStdout();
549 err = GetCapturedStderr();
550 return status;
551 }
552
Felipe Lemecef02982016-10-03 17:22:22 -0700553 // Dumps a file and capture `stdout` and `stderr`.
554 int DumpFile(const std::string& title, const std::string& path) {
555 CaptureStdout();
556 CaptureStderr();
557 int status = ds.DumpFile(title, path);
558 out = GetCapturedStdout();
559 err = GetCapturedStderr();
560 return status;
561 }
562
Nandana Dutt402a8392019-06-14 14:25:13 +0100563 void SetProgress(long progress, long initial_max) {
564 ds.last_reported_percent_progress_ = 0;
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100565 ds.options_->do_progress_updates = true;
Felipe Leme7447d7c2016-11-03 18:12:22 -0700566 ds.progress_.reset(new Progress(initial_max, progress, 1.2));
567 }
568
Abhijeet Kaured5d6a62019-10-07 15:02:05 +0100569 std::string GetProgressMessage(int progress, int max,
570 int old_max = 0, bool update_progress = true) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700571 EXPECT_EQ(progress, ds.progress_->Get()) << "invalid progress";
572 EXPECT_EQ(max, ds.progress_->GetMax()) << "invalid max";
Felipe Leme75876a22016-10-27 16:31:27 -0700573
Felipe Leme7447d7c2016-11-03 18:12:22 -0700574 bool max_increased = old_max > 0;
Felipe Leme75876a22016-10-27 16:31:27 -0700575
Felipe Leme009ecbb2016-11-07 10:18:44 -0800576 std::string message = "";
Felipe Leme75876a22016-10-27 16:31:27 -0700577 if (max_increased) {
Felipe Leme009ecbb2016-11-07 10:18:44 -0800578 message =
Felipe Leme7447d7c2016-11-03 18:12:22 -0700579 android::base::StringPrintf("Adjusting max progress from %d to %d\n", old_max, max);
Felipe Leme75876a22016-10-27 16:31:27 -0700580 }
581
Felipe Leme009ecbb2016-11-07 10:18:44 -0800582 if (update_progress) {
Abhijeet Kaured5d6a62019-10-07 15:02:05 +0100583 message += android::base::StringPrintf("Setting progress: %d/%d (%d%%)\n",
584 progress, max, (100 * progress / max));
Felipe Leme009ecbb2016-11-07 10:18:44 -0800585 }
586
587 return message;
Felipe Lemed80e6b62016-10-03 13:08:14 -0700588 }
589
Felipe Leme4c2d6632016-09-28 14:32:00 -0700590 // `stdout` and `stderr` from the last command ran.
591 std::string out, err;
592
Felipe Lemefd8affa2016-09-30 17:38:57 -0700593 Dumpstate& ds = Dumpstate::GetInstance();
Felipe Leme4c2d6632016-09-28 14:32:00 -0700594};
595
596TEST_F(DumpstateTest, RunCommandNoArgs) {
597 EXPECT_EQ(-1, RunCommand("", {}));
598}
599
600TEST_F(DumpstateTest, RunCommandNoTitle) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700601 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700602 EXPECT_THAT(out, StrEq("stdout\n"));
603 EXPECT_THAT(err, StrEq("stderr\n"));
604}
605
606TEST_F(DumpstateTest, RunCommandWithTitle) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700607 EXPECT_EQ(0, RunCommand("I AM GROOT", {kSimpleCommand}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700608 EXPECT_THAT(err, StrEq("stderr\n"));
Greg Kaiser3a811c12019-05-21 12:48:59 -0700609 // The duration may not get output, depending on how long it takes,
610 // so we just check the prefix.
Felipe Lemefd8affa2016-09-30 17:38:57 -0700611 EXPECT_THAT(out,
Nandana Dutt47527b52019-03-29 15:34:36 +0000612 StartsWith("------ I AM GROOT (" + kSimpleCommand + ") ------\nstdout\n"));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700613}
614
Felipe Lemefd8affa2016-09-30 17:38:57 -0700615TEST_F(DumpstateTest, RunCommandWithLoggingMessage) {
Felipe Leme4c2d6632016-09-28 14:32:00 -0700616 EXPECT_EQ(
Felipe Leme7447d7c2016-11-03 18:12:22 -0700617 0, RunCommand("", {kSimpleCommand},
Felipe Lemefd8affa2016-09-30 17:38:57 -0700618 CommandOptions::WithTimeout(10).Log("COMMAND, Y U NO LOG FIRST?").Build()));
619 EXPECT_THAT(out, StrEq("stdout\n"));
620 EXPECT_THAT(err, StrEq("COMMAND, Y U NO LOG FIRST?stderr\n"));
621}
622
623TEST_F(DumpstateTest, RunCommandRedirectStderr) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700624 EXPECT_EQ(0, RunCommand("", {kSimpleCommand},
Felipe Lemefd8affa2016-09-30 17:38:57 -0700625 CommandOptions::WithTimeout(10).RedirectStderr().Build()));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700626 EXPECT_THAT(out, IsEmpty());
Felipe Lemefd8affa2016-09-30 17:38:57 -0700627 EXPECT_THAT(err, StrEq("stdout\nstderr\n"));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700628}
629
630TEST_F(DumpstateTest, RunCommandWithOneArg) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700631 EXPECT_EQ(0, RunCommand("", {kEchoCommand, "one"}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700632 EXPECT_THAT(err, IsEmpty());
633 EXPECT_THAT(out, StrEq("one\n"));
634}
635
Felipe Lemefd8affa2016-09-30 17:38:57 -0700636TEST_F(DumpstateTest, RunCommandWithMultipleArgs) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700637 EXPECT_EQ(0, RunCommand("", {kEchoCommand, "one", "is", "the", "loniest", "number"}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700638 EXPECT_THAT(err, IsEmpty());
639 EXPECT_THAT(out, StrEq("one is the loniest number\n"));
640}
641
642TEST_F(DumpstateTest, RunCommandDryRun) {
643 SetDryRun(true);
Felipe Leme7447d7c2016-11-03 18:12:22 -0700644 EXPECT_EQ(0, RunCommand("I AM GROOT", {kSimpleCommand}));
Greg Kaiser3a811c12019-05-21 12:48:59 -0700645 // The duration may not get output, depending on how long it takes,
646 // so we just check the prefix.
Felipe Leme7447d7c2016-11-03 18:12:22 -0700647 EXPECT_THAT(out, StartsWith("------ I AM GROOT (" + kSimpleCommand +
Nandana Dutt47527b52019-03-29 15:34:36 +0000648 ") ------\n\t(skipped on dry run)\n"));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700649 EXPECT_THAT(err, IsEmpty());
650}
651
652TEST_F(DumpstateTest, RunCommandDryRunNoTitle) {
653 SetDryRun(true);
Felipe Leme7447d7c2016-11-03 18:12:22 -0700654 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700655 EXPECT_THAT(out, IsEmpty());
656 EXPECT_THAT(err, IsEmpty());
657}
658
659TEST_F(DumpstateTest, RunCommandDryRunAlways) {
660 SetDryRun(true);
Felipe Leme7447d7c2016-11-03 18:12:22 -0700661 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(10).Always().Build()));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700662 EXPECT_THAT(out, StrEq("stdout\n"));
663 EXPECT_THAT(err, StrEq("stderr\n"));
664}
665
Felipe Lemefd8affa2016-09-30 17:38:57 -0700666TEST_F(DumpstateTest, RunCommandNotFound) {
667 EXPECT_NE(0, RunCommand("", {"/there/cannot/be/such/command"}));
668 EXPECT_THAT(out, StartsWith("*** command '/there/cannot/be/such/command' failed: exit code"));
669 EXPECT_THAT(err, StartsWith("execvp on command '/there/cannot/be/such/command' failed"));
670}
671
672TEST_F(DumpstateTest, RunCommandFails) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700673 EXPECT_EQ(42, RunCommand("", {kSimpleCommand, "--exit", "42"}));
674 EXPECT_THAT(out, StrEq("stdout\n*** command '" + kSimpleCommand +
Felipe Leme9a523ae2016-10-20 15:10:33 -0700675 " --exit 42' failed: exit code 42\n"));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700676 EXPECT_THAT(err, StrEq("stderr\n*** command '" + kSimpleCommand +
Felipe Leme9a523ae2016-10-20 15:10:33 -0700677 " --exit 42' failed: exit code 42\n"));
Felipe Lemefd8affa2016-09-30 17:38:57 -0700678}
679
680TEST_F(DumpstateTest, RunCommandCrashes) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700681 EXPECT_NE(0, RunCommand("", {kSimpleCommand, "--crash"}));
Felipe Lemefd8affa2016-09-30 17:38:57 -0700682 // We don't know the exit code, so check just the prefix.
683 EXPECT_THAT(
Felipe Leme7447d7c2016-11-03 18:12:22 -0700684 out, StartsWith("stdout\n*** command '" + kSimpleCommand + " --crash' failed: exit code"));
Felipe Lemefd8affa2016-09-30 17:38:57 -0700685 EXPECT_THAT(
Felipe Leme7447d7c2016-11-03 18:12:22 -0700686 err, StartsWith("stderr\n*** command '" + kSimpleCommand + " --crash' failed: exit code"));
Felipe Lemefd8affa2016-09-30 17:38:57 -0700687}
688
689TEST_F(DumpstateTest, RunCommandTimesout) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700690 EXPECT_EQ(-1, RunCommand("", {kSimpleCommand, "--sleep", "2"},
Felipe Lemefd8affa2016-09-30 17:38:57 -0700691 CommandOptions::WithTimeout(1).Build()));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700692 EXPECT_THAT(out, StartsWith("stdout line1\n*** command '" + kSimpleCommand +
Felipe Lemefd8affa2016-09-30 17:38:57 -0700693 " --sleep 2' timed out after 1"));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700694 EXPECT_THAT(err, StartsWith("sleeping for 2s\n*** command '" + kSimpleCommand +
Felipe Lemefd8affa2016-09-30 17:38:57 -0700695 " --sleep 2' timed out after 1"));
696}
697
698TEST_F(DumpstateTest, RunCommandIsKilled) {
699 CaptureStdout();
700 CaptureStderr();
701
702 std::thread t([=]() {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700703 EXPECT_EQ(SIGTERM, ds.RunCommand("", {kSimpleCommand, "--pid", "--sleep", "20"},
Felipe Lemefd8affa2016-09-30 17:38:57 -0700704 CommandOptions::WithTimeout(100).Always().Build()));
705 });
706
707 // Capture pid and pre-sleep output.
708 sleep(1); // Wait a little bit to make sure pid and 1st line were printed.
709 std::string err = GetCapturedStderr();
710 EXPECT_THAT(err, StrEq("sleeping for 20s\n"));
711
712 std::string out = GetCapturedStdout();
713 std::vector<std::string> lines = android::base::Split(out, "\n");
714 ASSERT_EQ(3, (int)lines.size()) << "Invalid lines before sleep: " << out;
715
716 int pid = atoi(lines[0].c_str());
717 EXPECT_THAT(lines[1], StrEq("stdout line1"));
718 EXPECT_THAT(lines[2], IsEmpty()); // \n
719
720 // Then kill the process.
721 CaptureStdout();
722 CaptureStderr();
723 ASSERT_EQ(0, kill(pid, SIGTERM)) << "failed to kill pid " << pid;
724 t.join();
725
726 // Finally, check output after murder.
727 out = GetCapturedStdout();
728 err = GetCapturedStderr();
729
Felipe Leme7447d7c2016-11-03 18:12:22 -0700730 EXPECT_THAT(out, StrEq("*** command '" + kSimpleCommand +
Felipe Lemefd8affa2016-09-30 17:38:57 -0700731 " --pid --sleep 20' failed: killed by signal 15\n"));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700732 EXPECT_THAT(err, StrEq("*** command '" + kSimpleCommand +
Felipe Lemefd8affa2016-09-30 17:38:57 -0700733 " --pid --sleep 20' failed: killed by signal 15\n"));
734}
735
Felipe Leme75876a22016-10-27 16:31:27 -0700736TEST_F(DumpstateTest, RunCommandProgress) {
737 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
738 ds.listener_ = listener;
Felipe Leme7447d7c2016-11-03 18:12:22 -0700739 SetProgress(0, 30);
Felipe Leme75876a22016-10-27 16:31:27 -0700740
Nandana Duttbabf6c72019-01-15 14:11:12 +0000741 EXPECT_CALL(*listener, onProgress(66)); // 20/30 %
Felipe Leme7447d7c2016-11-03 18:12:22 -0700742 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(20).Build()));
Abhijeet Kaured5d6a62019-10-07 15:02:05 +0100743 std::string progress_message = GetProgressMessage(20, 30);
Felipe Leme75876a22016-10-27 16:31:27 -0700744 EXPECT_THAT(out, StrEq("stdout\n"));
745 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
746
Nandana Dutt402a8392019-06-14 14:25:13 +0100747 EXPECT_CALL(*listener, onProgress(80)); // 24/30 %
748 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(4).Build()));
Abhijeet Kaured5d6a62019-10-07 15:02:05 +0100749 progress_message = GetProgressMessage(24, 30);
Felipe Leme75876a22016-10-27 16:31:27 -0700750 EXPECT_THAT(out, StrEq("stdout\n"));
751 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
752
753 // Make sure command ran while in dry_run is counted.
754 SetDryRun(true);
Nandana Dutt402a8392019-06-14 14:25:13 +0100755 EXPECT_CALL(*listener, onProgress(90)); // 27/30 %
756 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(3).Build()));
Abhijeet Kaured5d6a62019-10-07 15:02:05 +0100757 progress_message = GetProgressMessage(27, 30);
Felipe Leme75876a22016-10-27 16:31:27 -0700758 EXPECT_THAT(out, IsEmpty());
759 EXPECT_THAT(err, StrEq(progress_message));
760
Nandana Dutt402a8392019-06-14 14:25:13 +0100761 SetDryRun(false);
762 EXPECT_CALL(*listener, onProgress(96)); // 29/30 %
763 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(2).Build()));
Abhijeet Kaured5d6a62019-10-07 15:02:05 +0100764 progress_message = GetProgressMessage(29, 30);
Felipe Leme009ecbb2016-11-07 10:18:44 -0800765 EXPECT_THAT(out, StrEq("stdout\n"));
766 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
767
Nandana Dutt402a8392019-06-14 14:25:13 +0100768 EXPECT_CALL(*listener, onProgress(100)); // 30/30 %
Felipe Leme009ecbb2016-11-07 10:18:44 -0800769 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).Build()));
Abhijeet Kaured5d6a62019-10-07 15:02:05 +0100770 progress_message = GetProgressMessage(30, 30);
Felipe Leme009ecbb2016-11-07 10:18:44 -0800771 EXPECT_THAT(out, StrEq("stdout\n"));
772 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
773
774 ds.listener_.clear();
775}
776
Felipe Lemed80e6b62016-10-03 13:08:14 -0700777TEST_F(DumpstateTest, RunCommandDropRoot) {
Felipe Leme46b85da2016-11-21 17:40:45 -0800778 if (!IsStandalone()) {
779 // TODO: temporarily disabled because it might cause other tests to fail after dropping
780 // to Shell - need to refactor tests to avoid this problem)
781 MYLOGE("Skipping DumpstateTest.RunCommandDropRoot() on test suite\n")
782 return;
783 }
Felipe Lemed80e6b62016-10-03 13:08:14 -0700784 // First check root case - only available when running with 'adb root'.
785 uid_t uid = getuid();
786 if (uid == 0) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700787 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"}));
Felipe Lemed80e6b62016-10-03 13:08:14 -0700788 EXPECT_THAT(out, StrEq("0\nstdout\n"));
789 EXPECT_THAT(err, StrEq("stderr\n"));
790 return;
791 }
Felipe Leme7447d7c2016-11-03 18:12:22 -0700792 // Then run dropping root.
793 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
Felipe Lemed80e6b62016-10-03 13:08:14 -0700794 CommandOptions::WithTimeout(1).DropRoot().Build()));
795 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
Felipe Leme26c41572016-10-06 14:34:43 -0700796 EXPECT_THAT(err, StrEq("drop_root_user(): already running as Shell\nstderr\n"));
Felipe Lemed80e6b62016-10-03 13:08:14 -0700797}
798
799TEST_F(DumpstateTest, RunCommandAsRootUserBuild) {
Felipe Leme46b85da2016-11-21 17:40:45 -0800800 if (!IsStandalone()) {
801 // TODO: temporarily disabled because it might cause other tests to fail after dropping
802 // to Shell - need to refactor tests to avoid this problem)
803 MYLOGE("Skipping DumpstateTest.RunCommandAsRootUserBuild() on test suite\n")
804 return;
805 }
Felipe Lemef0292972016-11-22 13:57:05 -0800806 if (!PropertiesHelper::IsUserBuild()) {
Felipe Lemed80e6b62016-10-03 13:08:14 -0700807 // Emulates user build if necessarily.
808 SetBuildType("user");
809 }
810
811 DropRoot();
812
Felipe Leme7447d7c2016-11-03 18:12:22 -0700813 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).AsRoot().Build()));
Felipe Lemed80e6b62016-10-03 13:08:14 -0700814
815 // We don't know the exact path of su, so we just check for the 'root ...' commands
816 EXPECT_THAT(out, StartsWith("Skipping"));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700817 EXPECT_THAT(out, EndsWith("root " + kSimpleCommand + "' on user build.\n"));
Felipe Lemed80e6b62016-10-03 13:08:14 -0700818 EXPECT_THAT(err, IsEmpty());
819}
820
Felipe Leme46b85da2016-11-21 17:40:45 -0800821TEST_F(DumpstateTest, RunCommandAsRootNonUserBuild) {
822 if (!IsStandalone()) {
823 // TODO: temporarily disabled because it might cause other tests to fail after dropping
824 // to Shell - need to refactor tests to avoid this problem)
825 MYLOGE("Skipping DumpstateTest.RunCommandAsRootNonUserBuild() on test suite\n")
826 return;
827 }
Felipe Lemef0292972016-11-22 13:57:05 -0800828 if (PropertiesHelper::IsUserBuild()) {
Felipe Leme46b85da2016-11-21 17:40:45 -0800829 ALOGI("Skipping RunCommandAsRootNonUserBuild on user builds\n");
830 return;
831 }
832
833 DropRoot();
834
835 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
836 CommandOptions::WithTimeout(1).AsRoot().Build()));
837
838 EXPECT_THAT(out, StrEq("0\nstdout\n"));
839 EXPECT_THAT(err, StrEq("stderr\n"));
840}
841
Nandana Dutt4b392be2018-11-02 16:17:05 +0000842TEST_F(DumpstateTest, RunCommandAsRootNonUserBuild_withUnroot) {
843 if (!IsStandalone()) {
844 // TODO: temporarily disabled because it might cause other tests to fail after dropping
845 // to Shell - need to refactor tests to avoid this problem)
846 MYLOGE(
847 "Skipping DumpstateTest.RunCommandAsRootNonUserBuild_withUnroot() "
848 "on test suite\n")
849 return;
850 }
851 if (PropertiesHelper::IsUserBuild()) {
852 ALOGI("Skipping RunCommandAsRootNonUserBuild_withUnroot on user builds\n");
853 return;
854 }
855
856 // Same test as above, but with unroot property set, which will override su availability.
857 SetUnroot(true);
858 DropRoot();
859
860 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
861 CommandOptions::WithTimeout(1).AsRoot().Build()));
862
863 // AsRoot is ineffective.
864 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
865 EXPECT_THAT(err, StrEq("drop_root_user(): already running as Shell\nstderr\n"));
866}
867
Yifan Hong48e83a12017-10-03 14:10:07 -0700868TEST_F(DumpstateTest, RunCommandAsRootIfAvailableOnUserBuild) {
869 if (!IsStandalone()) {
870 // TODO: temporarily disabled because it might cause other tests to fail after dropping
871 // to Shell - need to refactor tests to avoid this problem)
872 MYLOGE("Skipping DumpstateTest.RunCommandAsRootIfAvailableOnUserBuild() on test suite\n")
873 return;
874 }
875 if (!PropertiesHelper::IsUserBuild()) {
876 // Emulates user build if necessarily.
877 SetBuildType("user");
878 }
879
880 DropRoot();
881
882 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
883 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
884
885 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
886 EXPECT_THAT(err, StrEq("stderr\n"));
887}
888
889TEST_F(DumpstateTest, RunCommandAsRootIfAvailableOnDebugBuild) {
890 if (!IsStandalone()) {
891 // TODO: temporarily disabled because it might cause other tests to fail after dropping
892 // to Shell - need to refactor tests to avoid this problem)
893 MYLOGE("Skipping DumpstateTest.RunCommandAsRootIfAvailableOnDebugBuild() on test suite\n")
894 return;
895 }
896 if (PropertiesHelper::IsUserBuild()) {
897 ALOGI("Skipping RunCommandAsRootNonUserBuild on user builds\n");
898 return;
899 }
900
901 DropRoot();
902
903 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
904 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
905
906 EXPECT_THAT(out, StrEq("0\nstdout\n"));
907 EXPECT_THAT(err, StrEq("stderr\n"));
908}
909
Nandana Dutt4b392be2018-11-02 16:17:05 +0000910TEST_F(DumpstateTest, RunCommandAsRootIfAvailableOnDebugBuild_withUnroot) {
911 if (!IsStandalone()) {
912 // TODO: temporarily disabled because it might cause other tests to fail after dropping
913 // to Shell - need to refactor tests to avoid this problem)
914 MYLOGE(
915 "Skipping DumpstateTest.RunCommandAsRootIfAvailableOnDebugBuild_withUnroot() "
916 "on test suite\n")
917 return;
918 }
919 if (PropertiesHelper::IsUserBuild()) {
920 ALOGI("Skipping RunCommandAsRootIfAvailableOnDebugBuild_withUnroot on user builds\n");
921 return;
922 }
923 // Same test as above, but with unroot property set, which will override su availability.
924 SetUnroot(true);
925
926 DropRoot();
927
928 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
929 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
930
931 // It's a userdebug build, so "su root" should be available, but unroot=true overrides it.
932 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
933 EXPECT_THAT(err, StrEq("stderr\n"));
934}
935
Felipe Lemecef02982016-10-03 17:22:22 -0700936TEST_F(DumpstateTest, DumpFileNotFoundNoTitle) {
937 EXPECT_EQ(-1, DumpFile("", "/I/cant/believe/I/exist"));
938 EXPECT_THAT(out,
939 StrEq("*** Error dumping /I/cant/believe/I/exist: No such file or directory\n"));
940 EXPECT_THAT(err, IsEmpty());
941}
942
943TEST_F(DumpstateTest, DumpFileNotFoundWithTitle) {
944 EXPECT_EQ(-1, DumpFile("Y U NO EXIST?", "/I/cant/believe/I/exist"));
945 EXPECT_THAT(err, IsEmpty());
Greg Kaiser3a811c12019-05-21 12:48:59 -0700946 // The duration may not get output, depending on how long it takes,
947 // so we just check the prefix.
Felipe Lemecef02982016-10-03 17:22:22 -0700948 EXPECT_THAT(out, StartsWith("*** Error dumping /I/cant/believe/I/exist (Y U NO EXIST?): No "
949 "such file or directory\n"));
Felipe Lemecef02982016-10-03 17:22:22 -0700950}
951
952TEST_F(DumpstateTest, DumpFileSingleLine) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700953 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -0700954 EXPECT_THAT(err, IsEmpty());
955 EXPECT_THAT(out, StrEq("I AM LINE1\n")); // dumpstate adds missing newline
956}
957
958TEST_F(DumpstateTest, DumpFileSingleLineWithNewLine) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700959 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line-with-newline.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -0700960 EXPECT_THAT(err, IsEmpty());
961 EXPECT_THAT(out, StrEq("I AM LINE1\n"));
962}
963
964TEST_F(DumpstateTest, DumpFileMultipleLines) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700965 EXPECT_EQ(0, DumpFile("", kTestDataPath + "multiple-lines.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -0700966 EXPECT_THAT(err, IsEmpty());
967 EXPECT_THAT(out, StrEq("I AM LINE1\nI AM LINE2\nI AM LINE3\n"));
968}
969
970TEST_F(DumpstateTest, DumpFileMultipleLinesWithNewLine) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700971 EXPECT_EQ(0, DumpFile("", kTestDataPath + "multiple-lines-with-newline.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -0700972 EXPECT_THAT(err, IsEmpty());
973 EXPECT_THAT(out, StrEq("I AM LINE1\nI AM LINE2\nI AM LINE3\n"));
974}
975
976TEST_F(DumpstateTest, DumpFileOnDryRunNoTitle) {
977 SetDryRun(true);
Felipe Leme7447d7c2016-11-03 18:12:22 -0700978 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -0700979 EXPECT_THAT(err, IsEmpty());
980 EXPECT_THAT(out, IsEmpty());
981}
982
983TEST_F(DumpstateTest, DumpFileOnDryRun) {
984 SetDryRun(true);
Felipe Leme7447d7c2016-11-03 18:12:22 -0700985 EXPECT_EQ(0, DumpFile("Might as well dump. Dump!", kTestDataPath + "single-line.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -0700986 EXPECT_THAT(err, IsEmpty());
Felipe Leme46b85da2016-11-21 17:40:45 -0800987 EXPECT_THAT(
988 out, StartsWith("------ Might as well dump. Dump! (" + kTestDataPath + "single-line.txt:"));
Nandana Dutt47527b52019-03-29 15:34:36 +0000989 EXPECT_THAT(out, HasSubstr("\n\t(skipped on dry run)\n"));
Felipe Lemecef02982016-10-03 17:22:22 -0700990}
991
Felipe Leme75876a22016-10-27 16:31:27 -0700992TEST_F(DumpstateTest, DumpFileUpdateProgress) {
993 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
994 ds.listener_ = listener;
Felipe Leme7447d7c2016-11-03 18:12:22 -0700995 SetProgress(0, 30);
Felipe Leme75876a22016-10-27 16:31:27 -0700996
Nandana Duttbabf6c72019-01-15 14:11:12 +0000997 EXPECT_CALL(*listener, onProgress(16)); // 5/30 %
Felipe Leme7447d7c2016-11-03 18:12:22 -0700998 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
Felipe Leme75876a22016-10-27 16:31:27 -0700999
Abhijeet Kaured5d6a62019-10-07 15:02:05 +01001000 std::string progress_message = GetProgressMessage(5, 30); // TODO: unhardcode WEIGHT_FILE (5)?
Felipe Leme75876a22016-10-27 16:31:27 -07001001 EXPECT_THAT(err, StrEq(progress_message));
1002 EXPECT_THAT(out, StrEq("I AM LINE1\n")); // dumpstate adds missing newline
1003
1004 ds.listener_.clear();
1005}
1006
Felipe Leme7447d7c2016-11-03 18:12:22 -07001007class DumpstateServiceTest : public DumpstateBaseTest {
Felipe Leme75876a22016-10-27 16:31:27 -07001008 public:
1009 DumpstateService dss;
1010};
1011
Felipe Leme7447d7c2016-11-03 18:12:22 -07001012class ProgressTest : public DumpstateBaseTest {
1013 public:
1014 Progress GetInstance(int32_t max, double growth_factor, const std::string& path = "") {
1015 return Progress(max, growth_factor, path);
1016 }
1017
1018 void AssertStats(const std::string& path, int32_t expected_runs, int32_t expected_average) {
1019 std::string expected_content =
1020 android::base::StringPrintf("%d %d\n", expected_runs, expected_average);
1021 std::string actual_content;
Felipe Leme46b85da2016-11-21 17:40:45 -08001022 ReadFileToString(path, &actual_content);
Felipe Leme7447d7c2016-11-03 18:12:22 -07001023 ASSERT_THAT(actual_content, StrEq(expected_content)) << "invalid stats on " << path;
1024 }
1025};
1026
1027TEST_F(ProgressTest, SimpleTest) {
1028 Progress progress;
1029 EXPECT_EQ(0, progress.Get());
1030 EXPECT_EQ(Progress::kDefaultMax, progress.GetInitialMax());
1031 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1032
1033 bool max_increased = progress.Inc(1);
1034 EXPECT_EQ(1, progress.Get());
1035 EXPECT_EQ(Progress::kDefaultMax, progress.GetInitialMax());
1036 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1037 EXPECT_FALSE(max_increased);
1038
1039 // Ignore negative increase.
1040 max_increased = progress.Inc(-1);
1041 EXPECT_EQ(1, progress.Get());
1042 EXPECT_EQ(Progress::kDefaultMax, progress.GetInitialMax());
1043 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1044 EXPECT_FALSE(max_increased);
1045}
1046
1047TEST_F(ProgressTest, MaxGrowsInsideNewRange) {
1048 Progress progress = GetInstance(10, 1.2); // 20% growth factor
1049 EXPECT_EQ(0, progress.Get());
1050 EXPECT_EQ(10, progress.GetInitialMax());
1051 EXPECT_EQ(10, progress.GetMax());
1052
1053 // No increase
1054 bool max_increased = progress.Inc(10);
1055 EXPECT_EQ(10, progress.Get());
1056 EXPECT_EQ(10, progress.GetMax());
1057 EXPECT_FALSE(max_increased);
1058
1059 // Increase, with new value < max*20%
1060 max_increased = progress.Inc(1);
1061 EXPECT_EQ(11, progress.Get());
1062 EXPECT_EQ(13, progress.GetMax()); // 11 average * 20% growth = 13.2 = 13
1063 EXPECT_TRUE(max_increased);
1064}
1065
1066TEST_F(ProgressTest, MaxGrowsOutsideNewRange) {
1067 Progress progress = GetInstance(10, 1.2); // 20% growth factor
1068 EXPECT_EQ(0, progress.Get());
1069 EXPECT_EQ(10, progress.GetInitialMax());
1070 EXPECT_EQ(10, progress.GetMax());
1071
1072 // No increase
1073 bool max_increased = progress.Inc(10);
1074 EXPECT_EQ(10, progress.Get());
1075 EXPECT_EQ(10, progress.GetMax());
1076 EXPECT_FALSE(max_increased);
1077
1078 // Increase, with new value > max*20%
1079 max_increased = progress.Inc(5);
1080 EXPECT_EQ(15, progress.Get());
1081 EXPECT_EQ(18, progress.GetMax()); // 15 average * 20% growth = 18
1082 EXPECT_TRUE(max_increased);
1083}
1084
1085TEST_F(ProgressTest, InvalidPath) {
1086 Progress progress("/devil/null");
1087 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1088}
1089
1090TEST_F(ProgressTest, EmptyFile) {
1091 Progress progress(CopyTextFileFixture("empty-file.txt"));
1092 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1093}
1094
1095TEST_F(ProgressTest, InvalidLine1stEntryNAN) {
1096 Progress progress(CopyTextFileFixture("stats-invalid-1st-NAN.txt"));
1097 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1098}
1099
1100TEST_F(ProgressTest, InvalidLine2ndEntryNAN) {
1101 Progress progress(CopyTextFileFixture("stats-invalid-2nd-NAN.txt"));
1102 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1103}
1104
1105TEST_F(ProgressTest, InvalidLineBothNAN) {
1106 Progress progress(CopyTextFileFixture("stats-invalid-both-NAN.txt"));
1107 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1108}
1109
1110TEST_F(ProgressTest, InvalidLine1stEntryNegative) {
1111 Progress progress(CopyTextFileFixture("stats-invalid-1st-negative.txt"));
1112 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1113}
1114
1115TEST_F(ProgressTest, InvalidLine2ndEntryNegative) {
1116 Progress progress(CopyTextFileFixture("stats-invalid-2nd-negative.txt"));
1117 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1118}
1119
1120TEST_F(ProgressTest, InvalidLine1stEntryTooBig) {
1121 Progress progress(CopyTextFileFixture("stats-invalid-1st-too-big.txt"));
1122 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1123}
1124
1125TEST_F(ProgressTest, InvalidLine2ndEntryTooBig) {
1126 Progress progress(CopyTextFileFixture("stats-invalid-2nd-too-big.txt"));
1127 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1128}
1129
1130// Tests stats are properly saved when the file does not exists.
1131TEST_F(ProgressTest, FirstTime) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001132 if (!IsStandalone()) {
1133 // TODO: temporarily disabled because it's failing when running as suite
1134 MYLOGE("Skipping ProgressTest.FirstTime() on test suite\n")
1135 return;
1136 }
1137
Felipe Leme7447d7c2016-11-03 18:12:22 -07001138 std::string path = kTestDataPath + "FirstTime.txt";
1139 android::base::RemoveFileIfExists(path);
1140
1141 Progress run1(path);
1142 EXPECT_EQ(0, run1.Get());
1143 EXPECT_EQ(Progress::kDefaultMax, run1.GetInitialMax());
1144 EXPECT_EQ(Progress::kDefaultMax, run1.GetMax());
1145
1146 bool max_increased = run1.Inc(20);
1147 EXPECT_EQ(20, run1.Get());
1148 EXPECT_EQ(Progress::kDefaultMax, run1.GetMax());
1149 EXPECT_FALSE(max_increased);
1150
1151 run1.Save();
1152 AssertStats(path, 1, 20);
1153}
1154
1155// Tests what happens when the persistent settings contains the average duration of 1 run.
1156// Data on file is 1 run and 109 average.
1157TEST_F(ProgressTest, SecondTime) {
1158 std::string path = CopyTextFileFixture("stats-one-run-no-newline.txt");
1159
1160 Progress run1 = GetInstance(-42, 1.2, path);
1161 EXPECT_EQ(0, run1.Get());
1162 EXPECT_EQ(10, run1.GetInitialMax());
1163 EXPECT_EQ(10, run1.GetMax());
1164
1165 bool max_increased = run1.Inc(20);
1166 EXPECT_EQ(20, run1.Get());
1167 EXPECT_EQ(24, run1.GetMax());
1168 EXPECT_TRUE(max_increased);
1169
1170 // Average now is 2 runs and (10 + 20)/ 2 = 15
1171 run1.Save();
1172 AssertStats(path, 2, 15);
1173
1174 Progress run2 = GetInstance(-42, 1.2, path);
1175 EXPECT_EQ(0, run2.Get());
1176 EXPECT_EQ(15, run2.GetInitialMax());
1177 EXPECT_EQ(15, run2.GetMax());
1178
1179 max_increased = run2.Inc(25);
1180 EXPECT_EQ(25, run2.Get());
1181 EXPECT_EQ(30, run2.GetMax());
1182 EXPECT_TRUE(max_increased);
1183
1184 // Average now is 3 runs and (15 * 2 + 25)/ 3 = 18.33 = 18
1185 run2.Save();
1186 AssertStats(path, 3, 18);
1187
1188 Progress run3 = GetInstance(-42, 1.2, path);
1189 EXPECT_EQ(0, run3.Get());
1190 EXPECT_EQ(18, run3.GetInitialMax());
1191 EXPECT_EQ(18, run3.GetMax());
1192
1193 // Make sure average decreases as well
1194 max_increased = run3.Inc(5);
1195 EXPECT_EQ(5, run3.Get());
1196 EXPECT_EQ(18, run3.GetMax());
1197 EXPECT_FALSE(max_increased);
1198
1199 // Average now is 4 runs and (18 * 3 + 5)/ 4 = 14.75 = 14
1200 run3.Save();
1201 AssertStats(path, 4, 14);
1202}
1203
1204// Tests what happens when the persistent settings contains the average duration of 2 runs.
1205// Data on file is 2 runs and 15 average.
1206TEST_F(ProgressTest, ThirdTime) {
1207 std::string path = CopyTextFileFixture("stats-two-runs.txt");
1208 AssertStats(path, 2, 15); // Sanity check
1209
1210 Progress run1 = GetInstance(-42, 1.2, path);
1211 EXPECT_EQ(0, run1.Get());
1212 EXPECT_EQ(15, run1.GetInitialMax());
1213 EXPECT_EQ(15, run1.GetMax());
1214
1215 bool max_increased = run1.Inc(20);
1216 EXPECT_EQ(20, run1.Get());
1217 EXPECT_EQ(24, run1.GetMax());
1218 EXPECT_TRUE(max_increased);
1219
1220 // Average now is 3 runs and (15 * 2 + 20)/ 3 = 16.66 = 16
1221 run1.Save();
1222 AssertStats(path, 3, 16);
1223}
1224
Felipe Leme46b85da2016-11-21 17:40:45 -08001225class DumpstateUtilTest : public DumpstateBaseTest {
1226 public:
1227 void SetUp() {
1228 DumpstateBaseTest::SetUp();
1229 SetDryRun(false);
1230 }
1231
Felipe Leme46b85da2016-11-21 17:40:45 -08001232 void CaptureFdOut() {
Felipe Lemef0292972016-11-22 13:57:05 -08001233 ReadFileToString(path_, &out);
Felipe Leme46b85da2016-11-21 17:40:45 -08001234 }
1235
1236 void CreateFd(const std::string& name) {
1237 path_ = kTestDataPath + name;
1238 MYLOGD("Creating fd for file %s\n", path_.c_str());
1239
1240 fd = TEMP_FAILURE_RETRY(open(path_.c_str(),
1241 O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW,
1242 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH));
1243 ASSERT_GE(fd, 0) << "could not create FD for path " << path_;
1244 }
1245
1246 // Runs a command into the `fd` and capture `stderr`.
Felipe Lemef0292972016-11-22 13:57:05 -08001247 int RunCommand(const std::string& title, const std::vector<std::string>& full_command,
Felipe Leme46b85da2016-11-21 17:40:45 -08001248 const CommandOptions& options = CommandOptions::DEFAULT) {
1249 CaptureStderr();
Felipe Lemef0292972016-11-22 13:57:05 -08001250 int status = RunCommandToFd(fd, title, full_command, options);
Felipe Leme46b85da2016-11-21 17:40:45 -08001251 close(fd);
1252
1253 CaptureFdOut();
1254 err = GetCapturedStderr();
1255 return status;
1256 }
1257
1258 // Dumps a file and into the `fd` and `stderr`.
Felipe Lemef0292972016-11-22 13:57:05 -08001259 int DumpFile(const std::string& title, const std::string& path) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001260 CaptureStderr();
Felipe Lemef0292972016-11-22 13:57:05 -08001261 int status = DumpFileToFd(fd, title, path);
Felipe Leme46b85da2016-11-21 17:40:45 -08001262 close(fd);
1263
1264 CaptureFdOut();
1265 err = GetCapturedStderr();
1266 return status;
1267 }
1268
1269 int fd;
1270
1271 // 'fd` output and `stderr` from the last command ran.
1272 std::string out, err;
1273
1274 private:
1275 std::string path_;
1276};
1277
1278TEST_F(DumpstateUtilTest, RunCommandNoArgs) {
Felipe Lemef0292972016-11-22 13:57:05 -08001279 CreateFd("RunCommandNoArgs.txt");
1280 EXPECT_EQ(-1, RunCommand("", {}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001281}
1282
Felipe Lemef0292972016-11-22 13:57:05 -08001283TEST_F(DumpstateUtilTest, RunCommandNoTitle) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001284 CreateFd("RunCommandWithNoArgs.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001285 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001286 EXPECT_THAT(out, StrEq("stdout\n"));
1287 EXPECT_THAT(err, StrEq("stderr\n"));
1288}
1289
Felipe Lemef0292972016-11-22 13:57:05 -08001290TEST_F(DumpstateUtilTest, RunCommandWithTitle) {
1291 CreateFd("RunCommandWithNoArgs.txt");
1292 EXPECT_EQ(0, RunCommand("I AM GROOT", {kSimpleCommand}));
1293 EXPECT_THAT(out, StrEq("------ I AM GROOT (" + kSimpleCommand + ") ------\nstdout\n"));
1294 EXPECT_THAT(err, StrEq("stderr\n"));
1295}
1296
Felipe Leme46b85da2016-11-21 17:40:45 -08001297TEST_F(DumpstateUtilTest, RunCommandWithOneArg) {
1298 CreateFd("RunCommandWithOneArg.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001299 EXPECT_EQ(0, RunCommand("", {kEchoCommand, "one"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001300 EXPECT_THAT(err, IsEmpty());
1301 EXPECT_THAT(out, StrEq("one\n"));
1302}
1303
1304TEST_F(DumpstateUtilTest, RunCommandWithMultipleArgs) {
1305 CreateFd("RunCommandWithMultipleArgs.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001306 EXPECT_EQ(0, RunCommand("", {kEchoCommand, "one", "is", "the", "loniest", "number"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001307 EXPECT_THAT(err, IsEmpty());
1308 EXPECT_THAT(out, StrEq("one is the loniest number\n"));
1309}
1310
1311TEST_F(DumpstateUtilTest, RunCommandWithLoggingMessage) {
1312 CreateFd("RunCommandWithLoggingMessage.txt");
1313 EXPECT_EQ(
Felipe Lemef0292972016-11-22 13:57:05 -08001314 0, RunCommand("", {kSimpleCommand},
Felipe Leme46b85da2016-11-21 17:40:45 -08001315 CommandOptions::WithTimeout(10).Log("COMMAND, Y U NO LOG FIRST?").Build()));
1316 EXPECT_THAT(out, StrEq("stdout\n"));
1317 EXPECT_THAT(err, StrEq("COMMAND, Y U NO LOG FIRST?stderr\n"));
1318}
1319
1320TEST_F(DumpstateUtilTest, RunCommandRedirectStderr) {
1321 CreateFd("RunCommandRedirectStderr.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001322 EXPECT_EQ(0, RunCommand("", {kSimpleCommand},
1323 CommandOptions::WithTimeout(10).RedirectStderr().Build()));
Felipe Leme46b85da2016-11-21 17:40:45 -08001324 EXPECT_THAT(out, IsEmpty());
1325 EXPECT_THAT(err, StrEq("stdout\nstderr\n"));
1326}
1327
1328TEST_F(DumpstateUtilTest, RunCommandDryRun) {
1329 CreateFd("RunCommandDryRun.txt");
1330 SetDryRun(true);
Felipe Lemef0292972016-11-22 13:57:05 -08001331 EXPECT_EQ(0, RunCommand("I AM GROOT", {kSimpleCommand}));
1332 EXPECT_THAT(out, StrEq(android::base::StringPrintf(
1333 "------ I AM GROOT (%s) ------\n\t(skipped on dry run)\n",
1334 kSimpleCommand.c_str())));
1335 EXPECT_THAT(err, IsEmpty());
1336}
1337
1338TEST_F(DumpstateUtilTest, RunCommandDryRunNoTitle) {
1339 CreateFd("RunCommandDryRun.txt");
1340 SetDryRun(true);
1341 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001342 EXPECT_THAT(
1343 out, StrEq(android::base::StringPrintf("%s: skipped on dry run\n", kSimpleCommand.c_str())));
1344 EXPECT_THAT(err, IsEmpty());
1345}
1346
1347TEST_F(DumpstateUtilTest, RunCommandDryRunAlways) {
1348 CreateFd("RunCommandDryRunAlways.txt");
1349 SetDryRun(true);
Felipe Lemef0292972016-11-22 13:57:05 -08001350 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(10).Always().Build()));
Felipe Leme46b85da2016-11-21 17:40:45 -08001351 EXPECT_THAT(out, StrEq("stdout\n"));
1352 EXPECT_THAT(err, StrEq("stderr\n"));
1353}
1354
1355TEST_F(DumpstateUtilTest, RunCommandNotFound) {
1356 CreateFd("RunCommandNotFound.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001357 EXPECT_NE(0, RunCommand("", {"/there/cannot/be/such/command"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001358 EXPECT_THAT(out, StartsWith("*** command '/there/cannot/be/such/command' failed: exit code"));
1359 EXPECT_THAT(err, StartsWith("execvp on command '/there/cannot/be/such/command' failed"));
1360}
1361
1362TEST_F(DumpstateUtilTest, RunCommandFails) {
1363 CreateFd("RunCommandFails.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001364 EXPECT_EQ(42, RunCommand("", {kSimpleCommand, "--exit", "42"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001365 EXPECT_THAT(out, StrEq("stdout\n*** command '" + kSimpleCommand +
1366 " --exit 42' failed: exit code 42\n"));
1367 EXPECT_THAT(err, StrEq("stderr\n*** command '" + kSimpleCommand +
1368 " --exit 42' failed: exit code 42\n"));
1369}
1370
1371TEST_F(DumpstateUtilTest, RunCommandCrashes) {
1372 CreateFd("RunCommandCrashes.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001373 EXPECT_NE(0, RunCommand("", {kSimpleCommand, "--crash"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001374 // We don't know the exit code, so check just the prefix.
1375 EXPECT_THAT(
1376 out, StartsWith("stdout\n*** command '" + kSimpleCommand + " --crash' failed: exit code"));
1377 EXPECT_THAT(
1378 err, StartsWith("stderr\n*** command '" + kSimpleCommand + " --crash' failed: exit code"));
1379}
1380
Vishnu Nair6921f802017-11-22 09:17:23 -08001381TEST_F(DumpstateUtilTest, RunCommandTimesoutWithSec) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001382 CreateFd("RunCommandTimesout.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001383 EXPECT_EQ(-1, RunCommand("", {kSimpleCommand, "--sleep", "2"},
1384 CommandOptions::WithTimeout(1).Build()));
Felipe Leme46b85da2016-11-21 17:40:45 -08001385 EXPECT_THAT(out, StartsWith("stdout line1\n*** command '" + kSimpleCommand +
1386 " --sleep 2' timed out after 1"));
1387 EXPECT_THAT(err, StartsWith("sleeping for 2s\n*** command '" + kSimpleCommand +
1388 " --sleep 2' timed out after 1"));
1389}
1390
Vishnu Nair6921f802017-11-22 09:17:23 -08001391TEST_F(DumpstateUtilTest, RunCommandTimesoutWithMsec) {
1392 CreateFd("RunCommandTimesout.txt");
1393 EXPECT_EQ(-1, RunCommand("", {kSimpleCommand, "--sleep", "2"},
1394 CommandOptions::WithTimeoutInMs(1000).Build()));
1395 EXPECT_THAT(out, StartsWith("stdout line1\n*** command '" + kSimpleCommand +
1396 " --sleep 2' timed out after 1"));
1397 EXPECT_THAT(err, StartsWith("sleeping for 2s\n*** command '" + kSimpleCommand +
1398 " --sleep 2' timed out after 1"));
1399}
1400
1401
Felipe Leme46b85da2016-11-21 17:40:45 -08001402TEST_F(DumpstateUtilTest, RunCommandIsKilled) {
1403 CreateFd("RunCommandIsKilled.txt");
1404 CaptureStderr();
1405
1406 std::thread t([=]() {
Felipe Lemef0292972016-11-22 13:57:05 -08001407 EXPECT_EQ(SIGTERM, RunCommandToFd(fd, "", {kSimpleCommand, "--pid", "--sleep", "20"},
Felipe Leme46b85da2016-11-21 17:40:45 -08001408 CommandOptions::WithTimeout(100).Always().Build()));
1409 });
1410
1411 // Capture pid and pre-sleep output.
1412 sleep(1); // Wait a little bit to make sure pid and 1st line were printed.
1413 std::string err = GetCapturedStderr();
1414 EXPECT_THAT(err, StrEq("sleeping for 20s\n"));
1415
1416 CaptureFdOut();
1417 std::vector<std::string> lines = android::base::Split(out, "\n");
1418 ASSERT_EQ(3, (int)lines.size()) << "Invalid lines before sleep: " << out;
1419
1420 int pid = atoi(lines[0].c_str());
1421 EXPECT_THAT(lines[1], StrEq("stdout line1"));
1422 EXPECT_THAT(lines[2], IsEmpty()); // \n
1423
1424 // Then kill the process.
1425 CaptureFdOut();
1426 CaptureStderr();
1427 ASSERT_EQ(0, kill(pid, SIGTERM)) << "failed to kill pid " << pid;
1428 t.join();
1429
1430 // Finally, check output after murder.
1431 CaptureFdOut();
1432 err = GetCapturedStderr();
1433
1434 // out starts with the pid, which is an unknown
1435 EXPECT_THAT(out, EndsWith("stdout line1\n*** command '" + kSimpleCommand +
1436 " --pid --sleep 20' failed: killed by signal 15\n"));
1437 EXPECT_THAT(err, StrEq("*** command '" + kSimpleCommand +
1438 " --pid --sleep 20' failed: killed by signal 15\n"));
1439}
1440
1441TEST_F(DumpstateUtilTest, RunCommandAsRootUserBuild) {
1442 if (!IsStandalone()) {
1443 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1444 // to Shell - need to refactor tests to avoid this problem)
1445 MYLOGE("Skipping DumpstateUtilTest.RunCommandAsRootUserBuild() on test suite\n")
1446 return;
1447 }
1448 CreateFd("RunCommandAsRootUserBuild.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001449 if (!PropertiesHelper::IsUserBuild()) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001450 // Emulates user build if necessarily.
1451 SetBuildType("user");
1452 }
1453
1454 DropRoot();
1455
Felipe Lemef0292972016-11-22 13:57:05 -08001456 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).AsRoot().Build()));
Felipe Leme46b85da2016-11-21 17:40:45 -08001457
1458 // We don't know the exact path of su, so we just check for the 'root ...' commands
1459 EXPECT_THAT(out, StartsWith("Skipping"));
1460 EXPECT_THAT(out, EndsWith("root " + kSimpleCommand + "' on user build.\n"));
1461 EXPECT_THAT(err, IsEmpty());
1462}
1463
1464TEST_F(DumpstateUtilTest, RunCommandAsRootNonUserBuild) {
1465 if (!IsStandalone()) {
1466 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1467 // to Shell - need to refactor tests to avoid this problem)
1468 MYLOGE("Skipping DumpstateUtilTest.RunCommandAsRootNonUserBuild() on test suite\n")
1469 return;
1470 }
1471 CreateFd("RunCommandAsRootNonUserBuild.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001472 if (PropertiesHelper::IsUserBuild()) {
Felipe Leme7447d7c2016-11-03 18:12:22 -07001473 ALOGI("Skipping RunCommandAsRootNonUserBuild on user builds\n");
1474 return;
1475 }
1476
1477 DropRoot();
1478
Felipe Lemef0292972016-11-22 13:57:05 -08001479 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
1480 CommandOptions::WithTimeout(1).AsRoot().Build()));
Felipe Leme7447d7c2016-11-03 18:12:22 -07001481
1482 EXPECT_THAT(out, StrEq("0\nstdout\n"));
1483 EXPECT_THAT(err, StrEq("stderr\n"));
1484}
Felipe Leme46b85da2016-11-21 17:40:45 -08001485
Yifan Hong48e83a12017-10-03 14:10:07 -07001486
1487TEST_F(DumpstateUtilTest, RunCommandAsRootIfAvailableOnUserBuild) {
1488 if (!IsStandalone()) {
1489 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1490 // to Shell - need to refactor tests to avoid this problem)
1491 MYLOGE("Skipping DumpstateUtilTest.RunCommandAsRootIfAvailableOnUserBuild() on test suite\n")
1492 return;
1493 }
1494 CreateFd("RunCommandAsRootIfAvailableOnUserBuild.txt");
1495 if (!PropertiesHelper::IsUserBuild()) {
1496 // Emulates user build if necessarily.
1497 SetBuildType("user");
1498 }
1499
1500 DropRoot();
1501
1502 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
1503 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
1504
1505 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
1506 EXPECT_THAT(err, StrEq("stderr\n"));
1507}
1508
1509TEST_F(DumpstateUtilTest, RunCommandAsRootIfAvailableOnDebugBuild) {
1510 if (!IsStandalone()) {
1511 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1512 // to Shell - need to refactor tests to avoid this problem)
1513 MYLOGE("Skipping DumpstateUtilTest.RunCommandAsRootIfAvailableOnDebugBuild() on test suite\n")
1514 return;
1515 }
1516 CreateFd("RunCommandAsRootIfAvailableOnDebugBuild.txt");
1517 if (PropertiesHelper::IsUserBuild()) {
1518 ALOGI("Skipping RunCommandAsRootNonUserBuild on user builds\n");
1519 return;
1520 }
1521
1522 DropRoot();
1523
1524 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
1525 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
1526
1527 EXPECT_THAT(out, StrEq("0\nstdout\n"));
1528 EXPECT_THAT(err, StrEq("stderr\n"));
1529}
1530
Felipe Leme46b85da2016-11-21 17:40:45 -08001531TEST_F(DumpstateUtilTest, RunCommandDropRoot) {
1532 if (!IsStandalone()) {
1533 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1534 // to Shell - need to refactor tests to avoid this problem)
1535 MYLOGE("Skipping DumpstateUtilTest.RunCommandDropRoot() on test suite\n")
1536 return;
1537 }
1538 CreateFd("RunCommandDropRoot.txt");
1539 // First check root case - only available when running with 'adb root'.
1540 uid_t uid = getuid();
1541 if (uid == 0) {
Felipe Lemef0292972016-11-22 13:57:05 -08001542 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001543 EXPECT_THAT(out, StrEq("0\nstdout\n"));
1544 EXPECT_THAT(err, StrEq("stderr\n"));
1545 return;
1546 }
1547 // Then run dropping root.
Felipe Lemef0292972016-11-22 13:57:05 -08001548 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
Felipe Leme46b85da2016-11-21 17:40:45 -08001549 CommandOptions::WithTimeout(1).DropRoot().Build()));
1550 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
1551 EXPECT_THAT(err, StrEq("drop_root_user(): already running as Shell\nstderr\n"));
1552}
1553
Felipe Lemef0292972016-11-22 13:57:05 -08001554TEST_F(DumpstateUtilTest, DumpFileNotFoundNoTitle) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001555 CreateFd("DumpFileNotFound.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001556 EXPECT_EQ(-1, DumpFile("", "/I/cant/believe/I/exist"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001557 EXPECT_THAT(out,
1558 StrEq("*** Error dumping /I/cant/believe/I/exist: No such file or directory\n"));
1559 EXPECT_THAT(err, IsEmpty());
1560}
1561
Felipe Lemef0292972016-11-22 13:57:05 -08001562TEST_F(DumpstateUtilTest, DumpFileNotFoundWithTitle) {
1563 CreateFd("DumpFileNotFound.txt");
1564 EXPECT_EQ(-1, DumpFile("Y U NO EXIST?", "/I/cant/believe/I/exist"));
1565 EXPECT_THAT(out, StrEq("*** Error dumping /I/cant/believe/I/exist (Y U NO EXIST?): No such "
1566 "file or directory\n"));
1567 EXPECT_THAT(err, IsEmpty());
1568}
1569
Felipe Leme46b85da2016-11-21 17:40:45 -08001570TEST_F(DumpstateUtilTest, DumpFileSingleLine) {
1571 CreateFd("DumpFileSingleLine.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001572 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001573 EXPECT_THAT(err, IsEmpty());
1574 EXPECT_THAT(out, StrEq("I AM LINE1\n")); // dumpstate adds missing newline
1575}
1576
1577TEST_F(DumpstateUtilTest, DumpFileSingleLineWithNewLine) {
1578 CreateFd("DumpFileSingleLineWithNewLine.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001579 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line-with-newline.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001580 EXPECT_THAT(err, IsEmpty());
1581 EXPECT_THAT(out, StrEq("I AM LINE1\n"));
1582}
1583
1584TEST_F(DumpstateUtilTest, DumpFileMultipleLines) {
1585 CreateFd("DumpFileMultipleLines.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001586 EXPECT_EQ(0, DumpFile("", kTestDataPath + "multiple-lines.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001587 EXPECT_THAT(err, IsEmpty());
1588 EXPECT_THAT(out, StrEq("I AM LINE1\nI AM LINE2\nI AM LINE3\n"));
1589}
1590
1591TEST_F(DumpstateUtilTest, DumpFileMultipleLinesWithNewLine) {
1592 CreateFd("DumpFileMultipleLinesWithNewLine.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001593 EXPECT_EQ(0, DumpFile("", kTestDataPath + "multiple-lines-with-newline.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001594 EXPECT_THAT(err, IsEmpty());
1595 EXPECT_THAT(out, StrEq("I AM LINE1\nI AM LINE2\nI AM LINE3\n"));
1596}
1597
Felipe Lemef0292972016-11-22 13:57:05 -08001598TEST_F(DumpstateUtilTest, DumpFileOnDryRunNoTitle) {
1599 CreateFd("DumpFileOnDryRun.txt");
1600 SetDryRun(true);
1601 std::string path = kTestDataPath + "single-line.txt";
1602 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
1603 EXPECT_THAT(err, IsEmpty());
1604 EXPECT_THAT(out, StrEq(path + ": skipped on dry run\n"));
1605}
1606
Felipe Leme46b85da2016-11-21 17:40:45 -08001607TEST_F(DumpstateUtilTest, DumpFileOnDryRun) {
1608 CreateFd("DumpFileOnDryRun.txt");
1609 SetDryRun(true);
1610 std::string path = kTestDataPath + "single-line.txt";
Felipe Lemef0292972016-11-22 13:57:05 -08001611 EXPECT_EQ(0, DumpFile("Might as well dump. Dump!", kTestDataPath + "single-line.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001612 EXPECT_THAT(err, IsEmpty());
Felipe Lemef0292972016-11-22 13:57:05 -08001613 EXPECT_THAT(
1614 out, StartsWith("------ Might as well dump. Dump! (" + kTestDataPath + "single-line.txt:"));
1615 EXPECT_THAT(out, EndsWith("skipped on dry run\n"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001616}
Ecco Park61ffcf72016-10-27 15:46:26 -07001617
Felipe Leme47e9be22016-12-21 15:37:07 -08001618} // namespace dumpstate
1619} // namespace os
1620} // namespace android