blob: 0302c46ae80cd5e6e26e8c627882a1bdc04d3cd5 [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 Kaur904e0e02018-12-05 14:03:01 +000039#include <cutils/properties.h>
Felipe Leme4c2d6632016-09-28 14:32:00 -070040
Felipe Leme47e9be22016-12-21 15:37:07 -080041namespace android {
42namespace os {
43namespace dumpstate {
Felipe Lemed80e6b62016-10-03 13:08:14 -070044
Felipe Leme4c2d6632016-09-28 14:32:00 -070045using ::testing::EndsWith;
Felipe Leme46b85da2016-11-21 17:40:45 -080046using ::testing::HasSubstr;
Felipe Leme009ecbb2016-11-07 10:18:44 -080047using ::testing::IsNull;
Felipe Leme4c2d6632016-09-28 14:32:00 -070048using ::testing::IsEmpty;
Felipe Leme009ecbb2016-11-07 10:18:44 -080049using ::testing::NotNull;
Felipe Leme4c2d6632016-09-28 14:32:00 -070050using ::testing::StrEq;
51using ::testing::StartsWith;
52using ::testing::Test;
53using ::testing::internal::CaptureStderr;
54using ::testing::internal::CaptureStdout;
55using ::testing::internal::GetCapturedStderr;
56using ::testing::internal::GetCapturedStdout;
57
Nandana Dutt3f8c7172018-09-25 12:01:54 +010058#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
59
Felipe Leme75876a22016-10-27 16:31:27 -070060class DumpstateListenerMock : public IDumpstateListener {
61 public:
Nandana Dutta6a28bd2019-01-14 16:54:38 +000062 MOCK_METHOD1(onProgress, binder::Status(int32_t progress));
63 MOCK_METHOD1(onError, binder::Status(int32_t error_code));
64 MOCK_METHOD3(onFinished, binder::Status(int64_t duration_ms, const ::std::string& title,
65 const ::std::string& description));
Felipe Leme75876a22016-10-27 16:31:27 -070066 MOCK_METHOD1(onProgressUpdated, binder::Status(int32_t progress));
67 MOCK_METHOD1(onMaxProgressUpdated, binder::Status(int32_t max_progress));
Vishnu Nair20cf5032018-01-05 13:15:49 -080068 MOCK_METHOD4(onSectionComplete, binder::Status(const ::std::string& name, int32_t status,
69 int32_t size, int32_t durationMs));
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());
109 const std::string kFixturesPath = kTestPath + "/../dumpstate_test_fixture/";
Felipe Leme7fb8dee2017-08-25 10:15:01 -0700110 const std::string kTestDataPath = kFixturesPath + "tests/testdata/";
Felipe Leme7447d7c2016-11-03 18:12:22 -0700111 const std::string kSimpleCommand = kFixturesPath + "dumpstate_test_fixture";
112 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() {
157 // Reset the property
158 property_set("dumpstate.options", "");
159 }
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100160 Dumpstate::DumpOptions options_;
161};
162
163TEST_F(DumpOptionsTest, InitializeNone) {
164 // clang-format off
165 char* argv[] = {
166 const_cast<char*>("dumpstate")
167 };
168 // clang-format on
169
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100170 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
171
172 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
Nandana Dutt58d72e22018-11-16 10:30:48 +0000173
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100174 EXPECT_FALSE(options_.do_add_date);
175 EXPECT_FALSE(options_.do_zip_file);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100176 EXPECT_FALSE(options_.use_socket);
177 EXPECT_FALSE(options_.use_control_socket);
178 EXPECT_FALSE(options_.show_header_only);
179 EXPECT_TRUE(options_.do_vibrate);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000180 EXPECT_FALSE(options_.do_fb);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100181 EXPECT_FALSE(options_.do_progress_updates);
182 EXPECT_FALSE(options_.is_remote_mode);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000183 EXPECT_FALSE(options_.do_broadcast);
184}
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);
206 EXPECT_FALSE(options_.do_fb);
207 EXPECT_FALSE(options_.do_progress_updates);
208 EXPECT_FALSE(options_.is_remote_mode);
209 EXPECT_FALSE(options_.do_broadcast);
210 EXPECT_FALSE(options_.use_socket);
211}
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);
232 EXPECT_FALSE(options_.do_fb);
233 EXPECT_FALSE(options_.do_progress_updates);
234 EXPECT_FALSE(options_.is_remote_mode);
235 EXPECT_FALSE(options_.do_broadcast);
236}
237
238TEST_F(DumpOptionsTest, InitializeFullBugReport) {
239 // clang-format off
240 char* argv[] = {
241 const_cast<char*>("bugreport"),
242 const_cast<char*>("-d"),
243 const_cast<char*>("-p"),
244 const_cast<char*>("-B"),
245 const_cast<char*>("-z"),
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000246 };
247 // clang-format on
248 property_set("dumpstate.options", "bugreportfull");
249
250 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
251
252 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
253 EXPECT_TRUE(options_.do_add_date);
254 EXPECT_TRUE(options_.do_fb);
255 EXPECT_TRUE(options_.do_zip_file);
Nandana Dutt58d72e22018-11-16 10:30:48 +0000256 EXPECT_TRUE(options_.do_broadcast);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000257
258 // Other options retain default values
259 EXPECT_TRUE(options_.do_vibrate);
260 EXPECT_FALSE(options_.use_control_socket);
261 EXPECT_FALSE(options_.show_header_only);
262 EXPECT_FALSE(options_.do_progress_updates);
263 EXPECT_FALSE(options_.is_remote_mode);
264 EXPECT_FALSE(options_.use_socket);
265 EXPECT_FALSE(options_.do_start_service);
266}
267
268TEST_F(DumpOptionsTest, InitializeInteractiveBugReport) {
269 // clang-format off
270 char* argv[] = {
271 const_cast<char*>("bugreport"),
272 const_cast<char*>("-d"),
273 const_cast<char*>("-p"),
274 const_cast<char*>("-B"),
275 const_cast<char*>("-z"),
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000276 };
277 // clang-format on
278
279 property_set("dumpstate.options", "bugreportplus");
280
281 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
282
283 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
284 EXPECT_TRUE(options_.do_add_date);
285 EXPECT_TRUE(options_.do_broadcast);
286 EXPECT_TRUE(options_.do_zip_file);
287 EXPECT_TRUE(options_.do_progress_updates);
288 EXPECT_TRUE(options_.do_start_service);
289 EXPECT_FALSE(options_.do_fb);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000290
291 // Other options retain default values
292 EXPECT_TRUE(options_.do_vibrate);
293 EXPECT_FALSE(options_.use_control_socket);
294 EXPECT_FALSE(options_.show_header_only);
295 EXPECT_FALSE(options_.is_remote_mode);
296 EXPECT_FALSE(options_.use_socket);
297}
298
299TEST_F(DumpOptionsTest, InitializeRemoteBugReport) {
300 // clang-format off
301 char* argv[] = {
302 const_cast<char*>("bugreport"),
303 const_cast<char*>("-d"),
304 const_cast<char*>("-p"),
305 const_cast<char*>("-B"),
306 const_cast<char*>("-z"),
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000307 };
308 // clang-format on
309
310 property_set("dumpstate.options", "bugreportremote");
311
312 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
313
314 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
315 EXPECT_TRUE(options_.do_add_date);
316 EXPECT_TRUE(options_.do_broadcast);
317 EXPECT_TRUE(options_.do_zip_file);
318 EXPECT_TRUE(options_.is_remote_mode);
319 EXPECT_FALSE(options_.do_vibrate);
320 EXPECT_FALSE(options_.do_fb);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000321
322 // Other options retain default values
323 EXPECT_FALSE(options_.use_control_socket);
324 EXPECT_FALSE(options_.show_header_only);
325 EXPECT_FALSE(options_.do_progress_updates);
326 EXPECT_FALSE(options_.use_socket);
327}
328
329TEST_F(DumpOptionsTest, InitializeWearBugReport) {
330 // clang-format off
331 char* argv[] = {
332 const_cast<char*>("bugreport"),
333 const_cast<char*>("-d"),
334 const_cast<char*>("-p"),
335 const_cast<char*>("-B"),
336 const_cast<char*>("-z"),
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000337 };
338 // clang-format on
339
340 property_set("dumpstate.options", "bugreportwear");
341
342 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
343
344 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
345 EXPECT_TRUE(options_.do_add_date);
346 EXPECT_TRUE(options_.do_fb);
347 EXPECT_TRUE(options_.do_broadcast);
348 EXPECT_TRUE(options_.do_zip_file);
349 EXPECT_TRUE(options_.do_progress_updates);
350 EXPECT_TRUE(options_.do_start_service);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000351
352 // Other options retain default values
353 EXPECT_TRUE(options_.do_vibrate);
354 EXPECT_FALSE(options_.use_control_socket);
355 EXPECT_FALSE(options_.show_header_only);
356 EXPECT_FALSE(options_.is_remote_mode);
357 EXPECT_FALSE(options_.use_socket);
358}
359
360TEST_F(DumpOptionsTest, InitializeTelephonyBugReport) {
361 // clang-format off
362 char* argv[] = {
363 const_cast<char*>("bugreport"),
364 const_cast<char*>("-d"),
365 const_cast<char*>("-p"),
366 const_cast<char*>("-B"),
367 const_cast<char*>("-z"),
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000368 };
369 // clang-format on
370
371 property_set("dumpstate.options", "bugreporttelephony");
372
373 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
374
375 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
376 EXPECT_TRUE(options_.do_add_date);
377 EXPECT_TRUE(options_.do_fb);
378 EXPECT_TRUE(options_.do_broadcast);
379 EXPECT_TRUE(options_.do_zip_file);
380 EXPECT_TRUE(options_.telephony_only);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000381
382 // Other options retain default values
383 EXPECT_TRUE(options_.do_vibrate);
384 EXPECT_FALSE(options_.use_control_socket);
385 EXPECT_FALSE(options_.show_header_only);
386 EXPECT_FALSE(options_.do_progress_updates);
387 EXPECT_FALSE(options_.is_remote_mode);
388 EXPECT_FALSE(options_.use_socket);
389}
390
391TEST_F(DumpOptionsTest, InitializeWifiBugReport) {
392 // clang-format off
393 char* argv[] = {
394 const_cast<char*>("bugreport"),
395 const_cast<char*>("-d"),
396 const_cast<char*>("-p"),
397 const_cast<char*>("-B"),
398 const_cast<char*>("-z"),
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000399 };
400 // clang-format on
401
402 property_set("dumpstate.options", "bugreportwifi");
403
404 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
405
406 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
407 EXPECT_TRUE(options_.do_add_date);
408 EXPECT_TRUE(options_.do_fb);
409 EXPECT_TRUE(options_.do_broadcast);
410 EXPECT_TRUE(options_.do_zip_file);
411 EXPECT_TRUE(options_.wifi_only);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000412
413 // Other options retain default values
414 EXPECT_TRUE(options_.do_vibrate);
415 EXPECT_FALSE(options_.use_control_socket);
416 EXPECT_FALSE(options_.show_header_only);
417 EXPECT_FALSE(options_.do_progress_updates);
418 EXPECT_FALSE(options_.is_remote_mode);
419 EXPECT_FALSE(options_.use_socket);
420}
421
422TEST_F(DumpOptionsTest, InitializeDefaultBugReport) {
423 // default: commandline options are not overridden
424 // clang-format off
425 char* argv[] = {
426 const_cast<char*>("bugreport"),
427 const_cast<char*>("-d"),
428 const_cast<char*>("-p"),
429 const_cast<char*>("-B"),
430 const_cast<char*>("-z"),
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000431 };
432 // clang-format on
433
434 property_set("dumpstate.options", "");
435
436 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
437
438 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
439 EXPECT_TRUE(options_.do_add_date);
440 EXPECT_TRUE(options_.do_fb);
441 EXPECT_TRUE(options_.do_zip_file);
442 EXPECT_TRUE(options_.do_broadcast);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000443
444 // Other options retain default values
445 EXPECT_TRUE(options_.do_vibrate);
446 EXPECT_FALSE(options_.use_control_socket);
447 EXPECT_FALSE(options_.show_header_only);
448 EXPECT_FALSE(options_.do_progress_updates);
449 EXPECT_FALSE(options_.is_remote_mode);
450 EXPECT_FALSE(options_.use_socket);
451 EXPECT_FALSE(options_.wifi_only);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100452}
453
454TEST_F(DumpOptionsTest, InitializePartial1) {
455 // clang-format off
456 char* argv[] = {
457 const_cast<char*>("dumpstate"),
458 const_cast<char*>("-d"),
459 const_cast<char*>("-z"),
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100460 const_cast<char*>("-s"),
461 const_cast<char*>("-S"),
462
463 };
464 // clang-format on
465
466 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
467
468 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
469 EXPECT_TRUE(options_.do_add_date);
470 EXPECT_TRUE(options_.do_zip_file);
471 // TODO: Maybe we should trim the filename
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100472 EXPECT_TRUE(options_.use_socket);
473 EXPECT_TRUE(options_.use_control_socket);
474
475 // Other options retain default values
476 EXPECT_FALSE(options_.show_header_only);
477 EXPECT_TRUE(options_.do_vibrate);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000478 EXPECT_FALSE(options_.do_fb);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100479 EXPECT_FALSE(options_.do_progress_updates);
480 EXPECT_FALSE(options_.is_remote_mode);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000481 EXPECT_FALSE(options_.do_broadcast);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100482}
483
484TEST_F(DumpOptionsTest, InitializePartial2) {
485 // clang-format off
486 char* argv[] = {
487 const_cast<char*>("dumpstate"),
488 const_cast<char*>("-v"),
489 const_cast<char*>("-q"),
490 const_cast<char*>("-p"),
491 const_cast<char*>("-P"),
492 const_cast<char*>("-R"),
493 const_cast<char*>("-B"),
494 };
495 // clang-format on
496
497 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
498
499 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
500 EXPECT_TRUE(options_.show_header_only);
501 EXPECT_FALSE(options_.do_vibrate);
502 EXPECT_TRUE(options_.do_fb);
503 EXPECT_TRUE(options_.do_progress_updates);
504 EXPECT_TRUE(options_.is_remote_mode);
505 EXPECT_TRUE(options_.do_broadcast);
506
507 // Other options retain default values
508 EXPECT_FALSE(options_.do_add_date);
509 EXPECT_FALSE(options_.do_zip_file);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100510 EXPECT_FALSE(options_.use_socket);
511 EXPECT_FALSE(options_.use_control_socket);
512}
513
514TEST_F(DumpOptionsTest, InitializeHelp) {
515 // clang-format off
516 char* argv[] = {
517 const_cast<char*>("dumpstate"),
518 const_cast<char*>("-h")
519 };
520 // clang-format on
521
522 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
523
524 // -h is for help.
525 EXPECT_EQ(status, Dumpstate::RunStatus::HELP);
526}
527
528TEST_F(DumpOptionsTest, InitializeUnknown) {
529 // clang-format off
530 char* argv[] = {
531 const_cast<char*>("dumpstate"),
532 const_cast<char*>("-u") // unknown flag
533 };
534 // clang-format on
535
536 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
537
538 // -u is unknown.
539 EXPECT_EQ(status, Dumpstate::RunStatus::INVALID_INPUT);
540}
541
542TEST_F(DumpOptionsTest, ValidateOptionsNeedOutfile1) {
543 options_.do_zip_file = true;
Nandana Dutt9a76d202019-01-21 15:56:48 +0000544 // Writing to socket = !writing to file.
545 options_.use_socket = true;
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100546 EXPECT_FALSE(options_.ValidateOptions());
Nandana Dutt9a76d202019-01-21 15:56:48 +0000547
548 options_.use_socket = false;
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100549 EXPECT_TRUE(options_.ValidateOptions());
550}
551
552TEST_F(DumpOptionsTest, ValidateOptionsNeedOutfile2) {
553 options_.do_broadcast = true;
Nandana Dutt9a76d202019-01-21 15:56:48 +0000554 // Writing to socket = !writing to file.
555 options_.use_socket = true;
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100556 EXPECT_FALSE(options_.ValidateOptions());
Nandana Dutt9a76d202019-01-21 15:56:48 +0000557
558 options_.use_socket = false;
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100559 EXPECT_TRUE(options_.ValidateOptions());
560}
561
562TEST_F(DumpOptionsTest, ValidateOptionsNeedZipfile) {
563 options_.use_control_socket = true;
564 EXPECT_FALSE(options_.ValidateOptions());
565
566 options_.do_zip_file = true;
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100567 EXPECT_TRUE(options_.ValidateOptions());
568}
569
570TEST_F(DumpOptionsTest, ValidateOptionsUpdateProgressNeedsBroadcast) {
571 options_.do_progress_updates = true;
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100572 EXPECT_FALSE(options_.ValidateOptions());
573
574 options_.do_broadcast = true;
575 EXPECT_TRUE(options_.ValidateOptions());
576}
577
578TEST_F(DumpOptionsTest, ValidateOptionsRemoteMode) {
579 options_.is_remote_mode = true;
580 EXPECT_FALSE(options_.ValidateOptions());
581
582 options_.do_broadcast = true;
583 options_.do_zip_file = true;
584 options_.do_add_date = true;
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100585 EXPECT_TRUE(options_.ValidateOptions());
586}
587
Felipe Leme7447d7c2016-11-03 18:12:22 -0700588class DumpstateTest : public DumpstateBaseTest {
Felipe Leme4c2d6632016-09-28 14:32:00 -0700589 public:
590 void SetUp() {
Felipe Leme46b85da2016-11-21 17:40:45 -0800591 DumpstateBaseTest::SetUp();
Felipe Leme4c2d6632016-09-28 14:32:00 -0700592 SetDryRun(false);
Felipe Lemed80e6b62016-10-03 13:08:14 -0700593 SetBuildType(android::base::GetProperty("ro.build.type", "(unknown)"));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700594 ds.progress_.reset(new Progress());
Felipe Leme009ecbb2016-11-07 10:18:44 -0800595 ds.update_progress_threshold_ = 0;
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100596 ds.options_.reset(new Dumpstate::DumpOptions());
Felipe Leme4c2d6632016-09-28 14:32:00 -0700597 }
598
599 // Runs a command and capture `stdout` and `stderr`.
Felipe Leme9a523ae2016-10-20 15:10:33 -0700600 int RunCommand(const std::string& title, const std::vector<std::string>& full_command,
Felipe Leme4c2d6632016-09-28 14:32:00 -0700601 const CommandOptions& options = CommandOptions::DEFAULT) {
602 CaptureStdout();
603 CaptureStderr();
Felipe Leme9a523ae2016-10-20 15:10:33 -0700604 int status = ds.RunCommand(title, full_command, options);
Felipe Leme4c2d6632016-09-28 14:32:00 -0700605 out = GetCapturedStdout();
606 err = GetCapturedStderr();
607 return status;
608 }
609
Felipe Lemecef02982016-10-03 17:22:22 -0700610 // Dumps a file and capture `stdout` and `stderr`.
611 int DumpFile(const std::string& title, const std::string& path) {
612 CaptureStdout();
613 CaptureStderr();
614 int status = ds.DumpFile(title, path);
615 out = GetCapturedStdout();
616 err = GetCapturedStderr();
617 return status;
618 }
619
Felipe Leme009ecbb2016-11-07 10:18:44 -0800620 void SetProgress(long progress, long initial_max, long threshold = 0) {
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100621 ds.options_->do_progress_updates = true;
Felipe Leme009ecbb2016-11-07 10:18:44 -0800622 ds.update_progress_threshold_ = threshold;
623 ds.last_updated_progress_ = 0;
Felipe Leme7447d7c2016-11-03 18:12:22 -0700624 ds.progress_.reset(new Progress(initial_max, progress, 1.2));
625 }
626
Felipe Leme7447d7c2016-11-03 18:12:22 -0700627 std::string GetProgressMessage(const std::string& listener_name, int progress, int max,
Felipe Leme009ecbb2016-11-07 10:18:44 -0800628 int old_max = 0, bool update_progress = true) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700629 EXPECT_EQ(progress, ds.progress_->Get()) << "invalid progress";
630 EXPECT_EQ(max, ds.progress_->GetMax()) << "invalid max";
Felipe Leme75876a22016-10-27 16:31:27 -0700631
Felipe Leme7447d7c2016-11-03 18:12:22 -0700632 bool max_increased = old_max > 0;
Felipe Leme75876a22016-10-27 16:31:27 -0700633
Felipe Leme009ecbb2016-11-07 10:18:44 -0800634 std::string message = "";
Felipe Leme75876a22016-10-27 16:31:27 -0700635 if (max_increased) {
Felipe Leme009ecbb2016-11-07 10:18:44 -0800636 message =
Felipe Leme7447d7c2016-11-03 18:12:22 -0700637 android::base::StringPrintf("Adjusting max progress from %d to %d\n", old_max, max);
Felipe Leme75876a22016-10-27 16:31:27 -0700638 }
639
Felipe Leme009ecbb2016-11-07 10:18:44 -0800640 if (update_progress) {
Nandana Duttbabf6c72019-01-15 14:11:12 +0000641 message += android::base::StringPrintf("Setting progress (%s): %d/%d (%d%%)\n",
642 listener_name.c_str(), progress, max,
643 (100 * progress / max));
Felipe Leme009ecbb2016-11-07 10:18:44 -0800644 }
645
646 return message;
Felipe Lemed80e6b62016-10-03 13:08:14 -0700647 }
648
Felipe Leme4c2d6632016-09-28 14:32:00 -0700649 // `stdout` and `stderr` from the last command ran.
650 std::string out, err;
651
Felipe Lemefd8affa2016-09-30 17:38:57 -0700652 Dumpstate& ds = Dumpstate::GetInstance();
Felipe Leme4c2d6632016-09-28 14:32:00 -0700653};
654
655TEST_F(DumpstateTest, RunCommandNoArgs) {
656 EXPECT_EQ(-1, RunCommand("", {}));
657}
658
659TEST_F(DumpstateTest, RunCommandNoTitle) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700660 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700661 EXPECT_THAT(out, StrEq("stdout\n"));
662 EXPECT_THAT(err, StrEq("stderr\n"));
663}
664
665TEST_F(DumpstateTest, RunCommandWithTitle) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700666 EXPECT_EQ(0, RunCommand("I AM GROOT", {kSimpleCommand}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700667 EXPECT_THAT(err, StrEq("stderr\n"));
668 // We don't know the exact duration, so we check the prefix and suffix
Felipe Lemefd8affa2016-09-30 17:38:57 -0700669 EXPECT_THAT(out,
Felipe Leme7447d7c2016-11-03 18:12:22 -0700670 StartsWith("------ I AM GROOT (" + kSimpleCommand + ") ------\nstdout\n------"));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700671 EXPECT_THAT(out, EndsWith("s was the duration of 'I AM GROOT' ------\n"));
672}
673
Felipe Lemefd8affa2016-09-30 17:38:57 -0700674TEST_F(DumpstateTest, RunCommandWithLoggingMessage) {
Felipe Leme4c2d6632016-09-28 14:32:00 -0700675 EXPECT_EQ(
Felipe Leme7447d7c2016-11-03 18:12:22 -0700676 0, RunCommand("", {kSimpleCommand},
Felipe Lemefd8affa2016-09-30 17:38:57 -0700677 CommandOptions::WithTimeout(10).Log("COMMAND, Y U NO LOG FIRST?").Build()));
678 EXPECT_THAT(out, StrEq("stdout\n"));
679 EXPECT_THAT(err, StrEq("COMMAND, Y U NO LOG FIRST?stderr\n"));
680}
681
682TEST_F(DumpstateTest, RunCommandRedirectStderr) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700683 EXPECT_EQ(0, RunCommand("", {kSimpleCommand},
Felipe Lemefd8affa2016-09-30 17:38:57 -0700684 CommandOptions::WithTimeout(10).RedirectStderr().Build()));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700685 EXPECT_THAT(out, IsEmpty());
Felipe Lemefd8affa2016-09-30 17:38:57 -0700686 EXPECT_THAT(err, StrEq("stdout\nstderr\n"));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700687}
688
689TEST_F(DumpstateTest, RunCommandWithOneArg) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700690 EXPECT_EQ(0, RunCommand("", {kEchoCommand, "one"}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700691 EXPECT_THAT(err, IsEmpty());
692 EXPECT_THAT(out, StrEq("one\n"));
693}
694
Felipe Lemefd8affa2016-09-30 17:38:57 -0700695TEST_F(DumpstateTest, RunCommandWithMultipleArgs) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700696 EXPECT_EQ(0, RunCommand("", {kEchoCommand, "one", "is", "the", "loniest", "number"}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700697 EXPECT_THAT(err, IsEmpty());
698 EXPECT_THAT(out, StrEq("one is the loniest number\n"));
699}
700
701TEST_F(DumpstateTest, RunCommandDryRun) {
702 SetDryRun(true);
Felipe Leme7447d7c2016-11-03 18:12:22 -0700703 EXPECT_EQ(0, RunCommand("I AM GROOT", {kSimpleCommand}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700704 // We don't know the exact duration, so we check the prefix and suffix
Felipe Leme7447d7c2016-11-03 18:12:22 -0700705 EXPECT_THAT(out, StartsWith("------ I AM GROOT (" + kSimpleCommand +
Felipe Leme4c2d6632016-09-28 14:32:00 -0700706 ") ------\n\t(skipped on dry run)\n------"));
707 EXPECT_THAT(out, EndsWith("s was the duration of 'I AM GROOT' ------\n"));
708 EXPECT_THAT(err, IsEmpty());
709}
710
711TEST_F(DumpstateTest, RunCommandDryRunNoTitle) {
712 SetDryRun(true);
Felipe Leme7447d7c2016-11-03 18:12:22 -0700713 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700714 EXPECT_THAT(out, IsEmpty());
715 EXPECT_THAT(err, IsEmpty());
716}
717
718TEST_F(DumpstateTest, RunCommandDryRunAlways) {
719 SetDryRun(true);
Felipe Leme7447d7c2016-11-03 18:12:22 -0700720 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(10).Always().Build()));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700721 EXPECT_THAT(out, StrEq("stdout\n"));
722 EXPECT_THAT(err, StrEq("stderr\n"));
723}
724
Felipe Lemefd8affa2016-09-30 17:38:57 -0700725TEST_F(DumpstateTest, RunCommandNotFound) {
726 EXPECT_NE(0, RunCommand("", {"/there/cannot/be/such/command"}));
727 EXPECT_THAT(out, StartsWith("*** command '/there/cannot/be/such/command' failed: exit code"));
728 EXPECT_THAT(err, StartsWith("execvp on command '/there/cannot/be/such/command' failed"));
729}
730
731TEST_F(DumpstateTest, RunCommandFails) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700732 EXPECT_EQ(42, RunCommand("", {kSimpleCommand, "--exit", "42"}));
733 EXPECT_THAT(out, StrEq("stdout\n*** command '" + kSimpleCommand +
Felipe Leme9a523ae2016-10-20 15:10:33 -0700734 " --exit 42' failed: exit code 42\n"));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700735 EXPECT_THAT(err, StrEq("stderr\n*** command '" + kSimpleCommand +
Felipe Leme9a523ae2016-10-20 15:10:33 -0700736 " --exit 42' failed: exit code 42\n"));
Felipe Lemefd8affa2016-09-30 17:38:57 -0700737}
738
739TEST_F(DumpstateTest, RunCommandCrashes) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700740 EXPECT_NE(0, RunCommand("", {kSimpleCommand, "--crash"}));
Felipe Lemefd8affa2016-09-30 17:38:57 -0700741 // We don't know the exit code, so check just the prefix.
742 EXPECT_THAT(
Felipe Leme7447d7c2016-11-03 18:12:22 -0700743 out, StartsWith("stdout\n*** command '" + kSimpleCommand + " --crash' failed: exit code"));
Felipe Lemefd8affa2016-09-30 17:38:57 -0700744 EXPECT_THAT(
Felipe Leme7447d7c2016-11-03 18:12:22 -0700745 err, StartsWith("stderr\n*** command '" + kSimpleCommand + " --crash' failed: exit code"));
Felipe Lemefd8affa2016-09-30 17:38:57 -0700746}
747
748TEST_F(DumpstateTest, RunCommandTimesout) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700749 EXPECT_EQ(-1, RunCommand("", {kSimpleCommand, "--sleep", "2"},
Felipe Lemefd8affa2016-09-30 17:38:57 -0700750 CommandOptions::WithTimeout(1).Build()));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700751 EXPECT_THAT(out, StartsWith("stdout line1\n*** command '" + kSimpleCommand +
Felipe Lemefd8affa2016-09-30 17:38:57 -0700752 " --sleep 2' timed out after 1"));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700753 EXPECT_THAT(err, StartsWith("sleeping for 2s\n*** command '" + kSimpleCommand +
Felipe Lemefd8affa2016-09-30 17:38:57 -0700754 " --sleep 2' timed out after 1"));
755}
756
757TEST_F(DumpstateTest, RunCommandIsKilled) {
758 CaptureStdout();
759 CaptureStderr();
760
761 std::thread t([=]() {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700762 EXPECT_EQ(SIGTERM, ds.RunCommand("", {kSimpleCommand, "--pid", "--sleep", "20"},
Felipe Lemefd8affa2016-09-30 17:38:57 -0700763 CommandOptions::WithTimeout(100).Always().Build()));
764 });
765
766 // Capture pid and pre-sleep output.
767 sleep(1); // Wait a little bit to make sure pid and 1st line were printed.
768 std::string err = GetCapturedStderr();
769 EXPECT_THAT(err, StrEq("sleeping for 20s\n"));
770
771 std::string out = GetCapturedStdout();
772 std::vector<std::string> lines = android::base::Split(out, "\n");
773 ASSERT_EQ(3, (int)lines.size()) << "Invalid lines before sleep: " << out;
774
775 int pid = atoi(lines[0].c_str());
776 EXPECT_THAT(lines[1], StrEq("stdout line1"));
777 EXPECT_THAT(lines[2], IsEmpty()); // \n
778
779 // Then kill the process.
780 CaptureStdout();
781 CaptureStderr();
782 ASSERT_EQ(0, kill(pid, SIGTERM)) << "failed to kill pid " << pid;
783 t.join();
784
785 // Finally, check output after murder.
786 out = GetCapturedStdout();
787 err = GetCapturedStderr();
788
Felipe Leme7447d7c2016-11-03 18:12:22 -0700789 EXPECT_THAT(out, StrEq("*** command '" + kSimpleCommand +
Felipe Lemefd8affa2016-09-30 17:38:57 -0700790 " --pid --sleep 20' failed: killed by signal 15\n"));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700791 EXPECT_THAT(err, StrEq("*** command '" + kSimpleCommand +
Felipe Lemefd8affa2016-09-30 17:38:57 -0700792 " --pid --sleep 20' failed: killed by signal 15\n"));
793}
794
Felipe Leme75876a22016-10-27 16:31:27 -0700795TEST_F(DumpstateTest, RunCommandProgress) {
796 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
797 ds.listener_ = listener;
798 ds.listener_name_ = "FoxMulder";
Felipe Leme7447d7c2016-11-03 18:12:22 -0700799 SetProgress(0, 30);
Felipe Leme75876a22016-10-27 16:31:27 -0700800
801 EXPECT_CALL(*listener, onProgressUpdated(20));
Nandana Duttbabf6c72019-01-15 14:11:12 +0000802 EXPECT_CALL(*listener, onProgress(66)); // 20/30 %
Felipe Leme7447d7c2016-11-03 18:12:22 -0700803 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(20).Build()));
Felipe Leme75876a22016-10-27 16:31:27 -0700804 std::string progress_message = GetProgressMessage(ds.listener_name_, 20, 30);
805 EXPECT_THAT(out, StrEq("stdout\n"));
806 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
807
808 EXPECT_CALL(*listener, onProgressUpdated(30));
Nandana Duttbabf6c72019-01-15 14:11:12 +0000809 EXPECT_CALL(*listener, onProgress(100)); // 35/35 %
Felipe Leme7447d7c2016-11-03 18:12:22 -0700810 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(10).Build()));
Felipe Leme75876a22016-10-27 16:31:27 -0700811 progress_message = GetProgressMessage(ds.listener_name_, 30, 30);
812 EXPECT_THAT(out, StrEq("stdout\n"));
813 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
814
815 // Run a command that will increase maximum timeout.
816 EXPECT_CALL(*listener, onProgressUpdated(31));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700817 EXPECT_CALL(*listener, onMaxProgressUpdated(37));
Nandana Duttbabf6c72019-01-15 14:11:12 +0000818 EXPECT_CALL(*listener, onProgress(83)); // 31/37 %
Felipe Leme7447d7c2016-11-03 18:12:22 -0700819 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).Build()));
820 progress_message = GetProgressMessage(ds.listener_name_, 31, 37, 30); // 20% increase
Felipe Leme75876a22016-10-27 16:31:27 -0700821 EXPECT_THAT(out, StrEq("stdout\n"));
822 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
823
824 // Make sure command ran while in dry_run is counted.
825 SetDryRun(true);
826 EXPECT_CALL(*listener, onProgressUpdated(35));
Nandana Duttbabf6c72019-01-15 14:11:12 +0000827 EXPECT_CALL(*listener, onProgress(94)); // 35/37 %
Felipe Leme7447d7c2016-11-03 18:12:22 -0700828 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(4).Build()));
829 progress_message = GetProgressMessage(ds.listener_name_, 35, 37);
Felipe Leme75876a22016-10-27 16:31:27 -0700830 EXPECT_THAT(out, IsEmpty());
831 EXPECT_THAT(err, StrEq(progress_message));
832
833 ds.listener_.clear();
834}
835
Felipe Leme009ecbb2016-11-07 10:18:44 -0800836TEST_F(DumpstateTest, RunCommandProgressIgnoreThreshold) {
837 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
838 ds.listener_ = listener;
839 ds.listener_name_ = "FoxMulder";
840 SetProgress(0, 8, 5); // 8 max, 5 threshold
841
842 // First update should always be sent.
843 EXPECT_CALL(*listener, onProgressUpdated(1));
Nandana Duttbabf6c72019-01-15 14:11:12 +0000844 EXPECT_CALL(*listener, onProgress(12)); // 1/12 %
Felipe Leme009ecbb2016-11-07 10:18:44 -0800845 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).Build()));
846 std::string progress_message = GetProgressMessage(ds.listener_name_, 1, 8);
847 EXPECT_THAT(out, StrEq("stdout\n"));
848 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
849
850 // Fourth update should be ignored because it's between the threshold (5 -1 = 4 < 5).
851 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(4).Build()));
852 EXPECT_THAT(out, StrEq("stdout\n"));
853 EXPECT_THAT(err, StrEq("stderr\n"));
854
855 // Third update should be sent because it reaches threshold (6 - 1 = 5).
856 EXPECT_CALL(*listener, onProgressUpdated(6));
Nandana Duttbabf6c72019-01-15 14:11:12 +0000857 EXPECT_CALL(*listener, onProgress(75)); // 6/8 %
Felipe Leme009ecbb2016-11-07 10:18:44 -0800858 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).Build()));
859 progress_message = GetProgressMessage(ds.listener_name_, 6, 8);
860 EXPECT_THAT(out, StrEq("stdout\n"));
861 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
862
863 // Fourth update should be ignored because it's between the threshold (9 - 6 = 3 < 5).
864 // But max update should be sent.
865 EXPECT_CALL(*listener, onMaxProgressUpdated(10)); // 9 * 120% = 10.8 = 10
866 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(3).Build()));
867 progress_message = GetProgressMessage(ds.listener_name_, 9, 10, 8, false);
868 EXPECT_THAT(out, StrEq("stdout\n"));
869 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
870
871 ds.listener_.clear();
872}
873
Felipe Lemed80e6b62016-10-03 13:08:14 -0700874TEST_F(DumpstateTest, RunCommandDropRoot) {
Felipe Leme46b85da2016-11-21 17:40:45 -0800875 if (!IsStandalone()) {
876 // TODO: temporarily disabled because it might cause other tests to fail after dropping
877 // to Shell - need to refactor tests to avoid this problem)
878 MYLOGE("Skipping DumpstateTest.RunCommandDropRoot() on test suite\n")
879 return;
880 }
Felipe Lemed80e6b62016-10-03 13:08:14 -0700881 // First check root case - only available when running with 'adb root'.
882 uid_t uid = getuid();
883 if (uid == 0) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700884 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"}));
Felipe Lemed80e6b62016-10-03 13:08:14 -0700885 EXPECT_THAT(out, StrEq("0\nstdout\n"));
886 EXPECT_THAT(err, StrEq("stderr\n"));
887 return;
888 }
Felipe Leme7447d7c2016-11-03 18:12:22 -0700889 // Then run dropping root.
890 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
Felipe Lemed80e6b62016-10-03 13:08:14 -0700891 CommandOptions::WithTimeout(1).DropRoot().Build()));
892 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
Felipe Leme26c41572016-10-06 14:34:43 -0700893 EXPECT_THAT(err, StrEq("drop_root_user(): already running as Shell\nstderr\n"));
Felipe Lemed80e6b62016-10-03 13:08:14 -0700894}
895
896TEST_F(DumpstateTest, RunCommandAsRootUserBuild) {
Felipe Leme46b85da2016-11-21 17:40:45 -0800897 if (!IsStandalone()) {
898 // TODO: temporarily disabled because it might cause other tests to fail after dropping
899 // to Shell - need to refactor tests to avoid this problem)
900 MYLOGE("Skipping DumpstateTest.RunCommandAsRootUserBuild() on test suite\n")
901 return;
902 }
Felipe Lemef0292972016-11-22 13:57:05 -0800903 if (!PropertiesHelper::IsUserBuild()) {
Felipe Lemed80e6b62016-10-03 13:08:14 -0700904 // Emulates user build if necessarily.
905 SetBuildType("user");
906 }
907
908 DropRoot();
909
Felipe Leme7447d7c2016-11-03 18:12:22 -0700910 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).AsRoot().Build()));
Felipe Lemed80e6b62016-10-03 13:08:14 -0700911
912 // We don't know the exact path of su, so we just check for the 'root ...' commands
913 EXPECT_THAT(out, StartsWith("Skipping"));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700914 EXPECT_THAT(out, EndsWith("root " + kSimpleCommand + "' on user build.\n"));
Felipe Lemed80e6b62016-10-03 13:08:14 -0700915 EXPECT_THAT(err, IsEmpty());
916}
917
Felipe Leme46b85da2016-11-21 17:40:45 -0800918TEST_F(DumpstateTest, RunCommandAsRootNonUserBuild) {
919 if (!IsStandalone()) {
920 // TODO: temporarily disabled because it might cause other tests to fail after dropping
921 // to Shell - need to refactor tests to avoid this problem)
922 MYLOGE("Skipping DumpstateTest.RunCommandAsRootNonUserBuild() on test suite\n")
923 return;
924 }
Felipe Lemef0292972016-11-22 13:57:05 -0800925 if (PropertiesHelper::IsUserBuild()) {
Felipe Leme46b85da2016-11-21 17:40:45 -0800926 ALOGI("Skipping RunCommandAsRootNonUserBuild on user builds\n");
927 return;
928 }
929
930 DropRoot();
931
932 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
933 CommandOptions::WithTimeout(1).AsRoot().Build()));
934
935 EXPECT_THAT(out, StrEq("0\nstdout\n"));
936 EXPECT_THAT(err, StrEq("stderr\n"));
937}
938
Nandana Dutt4b392be2018-11-02 16:17:05 +0000939TEST_F(DumpstateTest, RunCommandAsRootNonUserBuild_withUnroot) {
940 if (!IsStandalone()) {
941 // TODO: temporarily disabled because it might cause other tests to fail after dropping
942 // to Shell - need to refactor tests to avoid this problem)
943 MYLOGE(
944 "Skipping DumpstateTest.RunCommandAsRootNonUserBuild_withUnroot() "
945 "on test suite\n")
946 return;
947 }
948 if (PropertiesHelper::IsUserBuild()) {
949 ALOGI("Skipping RunCommandAsRootNonUserBuild_withUnroot on user builds\n");
950 return;
951 }
952
953 // Same test as above, but with unroot property set, which will override su availability.
954 SetUnroot(true);
955 DropRoot();
956
957 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
958 CommandOptions::WithTimeout(1).AsRoot().Build()));
959
960 // AsRoot is ineffective.
961 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
962 EXPECT_THAT(err, StrEq("drop_root_user(): already running as Shell\nstderr\n"));
963}
964
Yifan Hong48e83a12017-10-03 14:10:07 -0700965TEST_F(DumpstateTest, RunCommandAsRootIfAvailableOnUserBuild) {
966 if (!IsStandalone()) {
967 // TODO: temporarily disabled because it might cause other tests to fail after dropping
968 // to Shell - need to refactor tests to avoid this problem)
969 MYLOGE("Skipping DumpstateTest.RunCommandAsRootIfAvailableOnUserBuild() on test suite\n")
970 return;
971 }
972 if (!PropertiesHelper::IsUserBuild()) {
973 // Emulates user build if necessarily.
974 SetBuildType("user");
975 }
976
977 DropRoot();
978
979 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
980 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
981
982 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
983 EXPECT_THAT(err, StrEq("stderr\n"));
984}
985
986TEST_F(DumpstateTest, RunCommandAsRootIfAvailableOnDebugBuild) {
987 if (!IsStandalone()) {
988 // TODO: temporarily disabled because it might cause other tests to fail after dropping
989 // to Shell - need to refactor tests to avoid this problem)
990 MYLOGE("Skipping DumpstateTest.RunCommandAsRootIfAvailableOnDebugBuild() on test suite\n")
991 return;
992 }
993 if (PropertiesHelper::IsUserBuild()) {
994 ALOGI("Skipping RunCommandAsRootNonUserBuild on user builds\n");
995 return;
996 }
997
998 DropRoot();
999
1000 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
1001 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
1002
1003 EXPECT_THAT(out, StrEq("0\nstdout\n"));
1004 EXPECT_THAT(err, StrEq("stderr\n"));
1005}
1006
Nandana Dutt4b392be2018-11-02 16:17:05 +00001007TEST_F(DumpstateTest, RunCommandAsRootIfAvailableOnDebugBuild_withUnroot) {
1008 if (!IsStandalone()) {
1009 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1010 // to Shell - need to refactor tests to avoid this problem)
1011 MYLOGE(
1012 "Skipping DumpstateTest.RunCommandAsRootIfAvailableOnDebugBuild_withUnroot() "
1013 "on test suite\n")
1014 return;
1015 }
1016 if (PropertiesHelper::IsUserBuild()) {
1017 ALOGI("Skipping RunCommandAsRootIfAvailableOnDebugBuild_withUnroot on user builds\n");
1018 return;
1019 }
1020 // Same test as above, but with unroot property set, which will override su availability.
1021 SetUnroot(true);
1022
1023 DropRoot();
1024
1025 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
1026 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
1027
1028 // It's a userdebug build, so "su root" should be available, but unroot=true overrides it.
1029 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
1030 EXPECT_THAT(err, StrEq("stderr\n"));
1031}
1032
Felipe Lemecef02982016-10-03 17:22:22 -07001033TEST_F(DumpstateTest, DumpFileNotFoundNoTitle) {
1034 EXPECT_EQ(-1, DumpFile("", "/I/cant/believe/I/exist"));
1035 EXPECT_THAT(out,
1036 StrEq("*** Error dumping /I/cant/believe/I/exist: No such file or directory\n"));
1037 EXPECT_THAT(err, IsEmpty());
1038}
1039
1040TEST_F(DumpstateTest, DumpFileNotFoundWithTitle) {
1041 EXPECT_EQ(-1, DumpFile("Y U NO EXIST?", "/I/cant/believe/I/exist"));
1042 EXPECT_THAT(err, IsEmpty());
1043 // We don't know the exact duration, so we check the prefix and suffix
1044 EXPECT_THAT(out, StartsWith("*** Error dumping /I/cant/believe/I/exist (Y U NO EXIST?): No "
1045 "such file or directory\n"));
1046 EXPECT_THAT(out, EndsWith("s was the duration of 'Y U NO EXIST?' ------\n"));
1047}
1048
1049TEST_F(DumpstateTest, DumpFileSingleLine) {
Felipe Leme7447d7c2016-11-03 18:12:22 -07001050 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -07001051 EXPECT_THAT(err, IsEmpty());
1052 EXPECT_THAT(out, StrEq("I AM LINE1\n")); // dumpstate adds missing newline
1053}
1054
1055TEST_F(DumpstateTest, DumpFileSingleLineWithNewLine) {
Felipe Leme7447d7c2016-11-03 18:12:22 -07001056 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line-with-newline.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -07001057 EXPECT_THAT(err, IsEmpty());
1058 EXPECT_THAT(out, StrEq("I AM LINE1\n"));
1059}
1060
1061TEST_F(DumpstateTest, DumpFileMultipleLines) {
Felipe Leme7447d7c2016-11-03 18:12:22 -07001062 EXPECT_EQ(0, DumpFile("", kTestDataPath + "multiple-lines.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -07001063 EXPECT_THAT(err, IsEmpty());
1064 EXPECT_THAT(out, StrEq("I AM LINE1\nI AM LINE2\nI AM LINE3\n"));
1065}
1066
1067TEST_F(DumpstateTest, DumpFileMultipleLinesWithNewLine) {
Felipe Leme7447d7c2016-11-03 18:12:22 -07001068 EXPECT_EQ(0, DumpFile("", kTestDataPath + "multiple-lines-with-newline.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -07001069 EXPECT_THAT(err, IsEmpty());
1070 EXPECT_THAT(out, StrEq("I AM LINE1\nI AM LINE2\nI AM LINE3\n"));
1071}
1072
1073TEST_F(DumpstateTest, DumpFileOnDryRunNoTitle) {
1074 SetDryRun(true);
Felipe Leme7447d7c2016-11-03 18:12:22 -07001075 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -07001076 EXPECT_THAT(err, IsEmpty());
1077 EXPECT_THAT(out, IsEmpty());
1078}
1079
1080TEST_F(DumpstateTest, DumpFileOnDryRun) {
1081 SetDryRun(true);
Felipe Leme7447d7c2016-11-03 18:12:22 -07001082 EXPECT_EQ(0, DumpFile("Might as well dump. Dump!", kTestDataPath + "single-line.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -07001083 EXPECT_THAT(err, IsEmpty());
Felipe Leme46b85da2016-11-21 17:40:45 -08001084 EXPECT_THAT(
1085 out, StartsWith("------ Might as well dump. Dump! (" + kTestDataPath + "single-line.txt:"));
1086 EXPECT_THAT(out, HasSubstr("\n\t(skipped on dry run)\n------"));
Felipe Lemecef02982016-10-03 17:22:22 -07001087 EXPECT_THAT(out, EndsWith("s was the duration of 'Might as well dump. Dump!' ------\n"));
Felipe Lemecef02982016-10-03 17:22:22 -07001088}
1089
Felipe Leme75876a22016-10-27 16:31:27 -07001090TEST_F(DumpstateTest, DumpFileUpdateProgress) {
1091 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
1092 ds.listener_ = listener;
1093 ds.listener_name_ = "FoxMulder";
Felipe Leme7447d7c2016-11-03 18:12:22 -07001094 SetProgress(0, 30);
Felipe Leme75876a22016-10-27 16:31:27 -07001095
1096 EXPECT_CALL(*listener, onProgressUpdated(5));
Nandana Duttbabf6c72019-01-15 14:11:12 +00001097 EXPECT_CALL(*listener, onProgress(16)); // 5/30 %
Felipe Leme7447d7c2016-11-03 18:12:22 -07001098 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
Felipe Leme75876a22016-10-27 16:31:27 -07001099
1100 std::string progress_message =
1101 GetProgressMessage(ds.listener_name_, 5, 30); // TODO: unhardcode WEIGHT_FILE (5)?
1102 EXPECT_THAT(err, StrEq(progress_message));
1103 EXPECT_THAT(out, StrEq("I AM LINE1\n")); // dumpstate adds missing newline
1104
1105 ds.listener_.clear();
1106}
1107
Felipe Leme7447d7c2016-11-03 18:12:22 -07001108class DumpstateServiceTest : public DumpstateBaseTest {
Felipe Leme75876a22016-10-27 16:31:27 -07001109 public:
1110 DumpstateService dss;
1111};
1112
1113TEST_F(DumpstateServiceTest, SetListenerNoName) {
1114 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
Felipe Leme009ecbb2016-11-07 10:18:44 -08001115 sp<IDumpstateToken> token;
Vishnu Nair20cf5032018-01-05 13:15:49 -08001116 EXPECT_TRUE(dss.setListener("", listener, /* getSectionDetails = */ false, &token).isOk());
Felipe Leme009ecbb2016-11-07 10:18:44 -08001117 ASSERT_THAT(token, IsNull());
Felipe Leme75876a22016-10-27 16:31:27 -07001118}
1119
1120TEST_F(DumpstateServiceTest, SetListenerNoPointer) {
Felipe Leme009ecbb2016-11-07 10:18:44 -08001121 sp<IDumpstateToken> token;
Vishnu Nair20cf5032018-01-05 13:15:49 -08001122 EXPECT_TRUE(
1123 dss.setListener("whatever", nullptr, /* getSectionDetails = */ false, &token).isOk());
Felipe Leme009ecbb2016-11-07 10:18:44 -08001124 ASSERT_THAT(token, IsNull());
Felipe Leme75876a22016-10-27 16:31:27 -07001125}
1126
1127TEST_F(DumpstateServiceTest, SetListenerTwice) {
1128 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
Felipe Leme009ecbb2016-11-07 10:18:44 -08001129 sp<IDumpstateToken> token;
Vishnu Nair20cf5032018-01-05 13:15:49 -08001130 EXPECT_TRUE(
1131 dss.setListener("whatever", listener, /* getSectionDetails = */ false, &token).isOk());
Felipe Leme009ecbb2016-11-07 10:18:44 -08001132 ASSERT_THAT(token, NotNull());
Felipe Leme75876a22016-10-27 16:31:27 -07001133 EXPECT_THAT(Dumpstate::GetInstance().listener_name_, StrEq("whatever"));
Vishnu Nair20cf5032018-01-05 13:15:49 -08001134 EXPECT_FALSE(Dumpstate::GetInstance().report_section_);
Felipe Leme75876a22016-10-27 16:31:27 -07001135
Felipe Leme009ecbb2016-11-07 10:18:44 -08001136 token.clear();
Vishnu Nair20cf5032018-01-05 13:15:49 -08001137 EXPECT_TRUE(
1138 dss.setListener("whatsoever", listener, /* getSectionDetails = */ false, &token).isOk());
Felipe Leme009ecbb2016-11-07 10:18:44 -08001139 ASSERT_THAT(token, IsNull());
1140 EXPECT_THAT(Dumpstate::GetInstance().listener_name_, StrEq("whatever"));
Vishnu Nair20cf5032018-01-05 13:15:49 -08001141 EXPECT_FALSE(Dumpstate::GetInstance().report_section_);
1142}
1143
1144TEST_F(DumpstateServiceTest, SetListenerWithSectionDetails) {
1145 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
1146 sp<IDumpstateToken> token;
1147 Dumpstate::GetInstance().listener_ = nullptr;
1148 EXPECT_TRUE(
1149 dss.setListener("whatever", listener, /* getSectionDetails = */ true, &token).isOk());
1150 ASSERT_THAT(token, NotNull());
1151 EXPECT_THAT(Dumpstate::GetInstance().listener_name_, StrEq("whatever"));
1152 EXPECT_TRUE(Dumpstate::GetInstance().report_section_);
Felipe Leme75876a22016-10-27 16:31:27 -07001153}
Felipe Leme7447d7c2016-11-03 18:12:22 -07001154
1155class ProgressTest : public DumpstateBaseTest {
1156 public:
1157 Progress GetInstance(int32_t max, double growth_factor, const std::string& path = "") {
1158 return Progress(max, growth_factor, path);
1159 }
1160
1161 void AssertStats(const std::string& path, int32_t expected_runs, int32_t expected_average) {
1162 std::string expected_content =
1163 android::base::StringPrintf("%d %d\n", expected_runs, expected_average);
1164 std::string actual_content;
Felipe Leme46b85da2016-11-21 17:40:45 -08001165 ReadFileToString(path, &actual_content);
Felipe Leme7447d7c2016-11-03 18:12:22 -07001166 ASSERT_THAT(actual_content, StrEq(expected_content)) << "invalid stats on " << path;
1167 }
1168};
1169
1170TEST_F(ProgressTest, SimpleTest) {
1171 Progress progress;
1172 EXPECT_EQ(0, progress.Get());
1173 EXPECT_EQ(Progress::kDefaultMax, progress.GetInitialMax());
1174 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1175
1176 bool max_increased = progress.Inc(1);
1177 EXPECT_EQ(1, progress.Get());
1178 EXPECT_EQ(Progress::kDefaultMax, progress.GetInitialMax());
1179 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1180 EXPECT_FALSE(max_increased);
1181
1182 // Ignore negative increase.
1183 max_increased = progress.Inc(-1);
1184 EXPECT_EQ(1, progress.Get());
1185 EXPECT_EQ(Progress::kDefaultMax, progress.GetInitialMax());
1186 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1187 EXPECT_FALSE(max_increased);
1188}
1189
1190TEST_F(ProgressTest, MaxGrowsInsideNewRange) {
1191 Progress progress = GetInstance(10, 1.2); // 20% growth factor
1192 EXPECT_EQ(0, progress.Get());
1193 EXPECT_EQ(10, progress.GetInitialMax());
1194 EXPECT_EQ(10, progress.GetMax());
1195
1196 // No increase
1197 bool max_increased = progress.Inc(10);
1198 EXPECT_EQ(10, progress.Get());
1199 EXPECT_EQ(10, progress.GetMax());
1200 EXPECT_FALSE(max_increased);
1201
1202 // Increase, with new value < max*20%
1203 max_increased = progress.Inc(1);
1204 EXPECT_EQ(11, progress.Get());
1205 EXPECT_EQ(13, progress.GetMax()); // 11 average * 20% growth = 13.2 = 13
1206 EXPECT_TRUE(max_increased);
1207}
1208
1209TEST_F(ProgressTest, MaxGrowsOutsideNewRange) {
1210 Progress progress = GetInstance(10, 1.2); // 20% growth factor
1211 EXPECT_EQ(0, progress.Get());
1212 EXPECT_EQ(10, progress.GetInitialMax());
1213 EXPECT_EQ(10, progress.GetMax());
1214
1215 // No increase
1216 bool max_increased = progress.Inc(10);
1217 EXPECT_EQ(10, progress.Get());
1218 EXPECT_EQ(10, progress.GetMax());
1219 EXPECT_FALSE(max_increased);
1220
1221 // Increase, with new value > max*20%
1222 max_increased = progress.Inc(5);
1223 EXPECT_EQ(15, progress.Get());
1224 EXPECT_EQ(18, progress.GetMax()); // 15 average * 20% growth = 18
1225 EXPECT_TRUE(max_increased);
1226}
1227
1228TEST_F(ProgressTest, InvalidPath) {
1229 Progress progress("/devil/null");
1230 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1231}
1232
1233TEST_F(ProgressTest, EmptyFile) {
1234 Progress progress(CopyTextFileFixture("empty-file.txt"));
1235 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1236}
1237
1238TEST_F(ProgressTest, InvalidLine1stEntryNAN) {
1239 Progress progress(CopyTextFileFixture("stats-invalid-1st-NAN.txt"));
1240 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1241}
1242
1243TEST_F(ProgressTest, InvalidLine2ndEntryNAN) {
1244 Progress progress(CopyTextFileFixture("stats-invalid-2nd-NAN.txt"));
1245 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1246}
1247
1248TEST_F(ProgressTest, InvalidLineBothNAN) {
1249 Progress progress(CopyTextFileFixture("stats-invalid-both-NAN.txt"));
1250 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1251}
1252
1253TEST_F(ProgressTest, InvalidLine1stEntryNegative) {
1254 Progress progress(CopyTextFileFixture("stats-invalid-1st-negative.txt"));
1255 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1256}
1257
1258TEST_F(ProgressTest, InvalidLine2ndEntryNegative) {
1259 Progress progress(CopyTextFileFixture("stats-invalid-2nd-negative.txt"));
1260 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1261}
1262
1263TEST_F(ProgressTest, InvalidLine1stEntryTooBig) {
1264 Progress progress(CopyTextFileFixture("stats-invalid-1st-too-big.txt"));
1265 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1266}
1267
1268TEST_F(ProgressTest, InvalidLine2ndEntryTooBig) {
1269 Progress progress(CopyTextFileFixture("stats-invalid-2nd-too-big.txt"));
1270 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1271}
1272
1273// Tests stats are properly saved when the file does not exists.
1274TEST_F(ProgressTest, FirstTime) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001275 if (!IsStandalone()) {
1276 // TODO: temporarily disabled because it's failing when running as suite
1277 MYLOGE("Skipping ProgressTest.FirstTime() on test suite\n")
1278 return;
1279 }
1280
Felipe Leme7447d7c2016-11-03 18:12:22 -07001281 std::string path = kTestDataPath + "FirstTime.txt";
1282 android::base::RemoveFileIfExists(path);
1283
1284 Progress run1(path);
1285 EXPECT_EQ(0, run1.Get());
1286 EXPECT_EQ(Progress::kDefaultMax, run1.GetInitialMax());
1287 EXPECT_EQ(Progress::kDefaultMax, run1.GetMax());
1288
1289 bool max_increased = run1.Inc(20);
1290 EXPECT_EQ(20, run1.Get());
1291 EXPECT_EQ(Progress::kDefaultMax, run1.GetMax());
1292 EXPECT_FALSE(max_increased);
1293
1294 run1.Save();
1295 AssertStats(path, 1, 20);
1296}
1297
1298// Tests what happens when the persistent settings contains the average duration of 1 run.
1299// Data on file is 1 run and 109 average.
1300TEST_F(ProgressTest, SecondTime) {
1301 std::string path = CopyTextFileFixture("stats-one-run-no-newline.txt");
1302
1303 Progress run1 = GetInstance(-42, 1.2, path);
1304 EXPECT_EQ(0, run1.Get());
1305 EXPECT_EQ(10, run1.GetInitialMax());
1306 EXPECT_EQ(10, run1.GetMax());
1307
1308 bool max_increased = run1.Inc(20);
1309 EXPECT_EQ(20, run1.Get());
1310 EXPECT_EQ(24, run1.GetMax());
1311 EXPECT_TRUE(max_increased);
1312
1313 // Average now is 2 runs and (10 + 20)/ 2 = 15
1314 run1.Save();
1315 AssertStats(path, 2, 15);
1316
1317 Progress run2 = GetInstance(-42, 1.2, path);
1318 EXPECT_EQ(0, run2.Get());
1319 EXPECT_EQ(15, run2.GetInitialMax());
1320 EXPECT_EQ(15, run2.GetMax());
1321
1322 max_increased = run2.Inc(25);
1323 EXPECT_EQ(25, run2.Get());
1324 EXPECT_EQ(30, run2.GetMax());
1325 EXPECT_TRUE(max_increased);
1326
1327 // Average now is 3 runs and (15 * 2 + 25)/ 3 = 18.33 = 18
1328 run2.Save();
1329 AssertStats(path, 3, 18);
1330
1331 Progress run3 = GetInstance(-42, 1.2, path);
1332 EXPECT_EQ(0, run3.Get());
1333 EXPECT_EQ(18, run3.GetInitialMax());
1334 EXPECT_EQ(18, run3.GetMax());
1335
1336 // Make sure average decreases as well
1337 max_increased = run3.Inc(5);
1338 EXPECT_EQ(5, run3.Get());
1339 EXPECT_EQ(18, run3.GetMax());
1340 EXPECT_FALSE(max_increased);
1341
1342 // Average now is 4 runs and (18 * 3 + 5)/ 4 = 14.75 = 14
1343 run3.Save();
1344 AssertStats(path, 4, 14);
1345}
1346
1347// Tests what happens when the persistent settings contains the average duration of 2 runs.
1348// Data on file is 2 runs and 15 average.
1349TEST_F(ProgressTest, ThirdTime) {
1350 std::string path = CopyTextFileFixture("stats-two-runs.txt");
1351 AssertStats(path, 2, 15); // Sanity check
1352
1353 Progress run1 = GetInstance(-42, 1.2, path);
1354 EXPECT_EQ(0, run1.Get());
1355 EXPECT_EQ(15, run1.GetInitialMax());
1356 EXPECT_EQ(15, run1.GetMax());
1357
1358 bool max_increased = run1.Inc(20);
1359 EXPECT_EQ(20, run1.Get());
1360 EXPECT_EQ(24, run1.GetMax());
1361 EXPECT_TRUE(max_increased);
1362
1363 // Average now is 3 runs and (15 * 2 + 20)/ 3 = 16.66 = 16
1364 run1.Save();
1365 AssertStats(path, 3, 16);
1366}
1367
Felipe Leme46b85da2016-11-21 17:40:45 -08001368class DumpstateUtilTest : public DumpstateBaseTest {
1369 public:
1370 void SetUp() {
1371 DumpstateBaseTest::SetUp();
1372 SetDryRun(false);
1373 }
1374
Felipe Leme46b85da2016-11-21 17:40:45 -08001375 void CaptureFdOut() {
Felipe Lemef0292972016-11-22 13:57:05 -08001376 ReadFileToString(path_, &out);
Felipe Leme46b85da2016-11-21 17:40:45 -08001377 }
1378
1379 void CreateFd(const std::string& name) {
1380 path_ = kTestDataPath + name;
1381 MYLOGD("Creating fd for file %s\n", path_.c_str());
1382
1383 fd = TEMP_FAILURE_RETRY(open(path_.c_str(),
1384 O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW,
1385 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH));
1386 ASSERT_GE(fd, 0) << "could not create FD for path " << path_;
1387 }
1388
1389 // Runs a command into the `fd` and capture `stderr`.
Felipe Lemef0292972016-11-22 13:57:05 -08001390 int RunCommand(const std::string& title, const std::vector<std::string>& full_command,
Felipe Leme46b85da2016-11-21 17:40:45 -08001391 const CommandOptions& options = CommandOptions::DEFAULT) {
1392 CaptureStderr();
Felipe Lemef0292972016-11-22 13:57:05 -08001393 int status = RunCommandToFd(fd, title, full_command, options);
Felipe Leme46b85da2016-11-21 17:40:45 -08001394 close(fd);
1395
1396 CaptureFdOut();
1397 err = GetCapturedStderr();
1398 return status;
1399 }
1400
1401 // Dumps a file and into the `fd` and `stderr`.
Felipe Lemef0292972016-11-22 13:57:05 -08001402 int DumpFile(const std::string& title, const std::string& path) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001403 CaptureStderr();
Felipe Lemef0292972016-11-22 13:57:05 -08001404 int status = DumpFileToFd(fd, title, path);
Felipe Leme46b85da2016-11-21 17:40:45 -08001405 close(fd);
1406
1407 CaptureFdOut();
1408 err = GetCapturedStderr();
1409 return status;
1410 }
1411
Ecco Park61ffcf72016-10-27 15:46:26 -07001412 // Find out the pid of the process_name
1413 int FindPidOfProcess(const std::string& process_name) {
1414 CaptureStderr();
1415 int status = GetPidByName(process_name);
1416 err = GetCapturedStderr();
1417 return status;
1418 }
1419
Felipe Leme46b85da2016-11-21 17:40:45 -08001420 int fd;
1421
1422 // 'fd` output and `stderr` from the last command ran.
1423 std::string out, err;
1424
1425 private:
1426 std::string path_;
1427};
1428
1429TEST_F(DumpstateUtilTest, RunCommandNoArgs) {
Felipe Lemef0292972016-11-22 13:57:05 -08001430 CreateFd("RunCommandNoArgs.txt");
1431 EXPECT_EQ(-1, RunCommand("", {}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001432}
1433
Felipe Lemef0292972016-11-22 13:57:05 -08001434TEST_F(DumpstateUtilTest, RunCommandNoTitle) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001435 CreateFd("RunCommandWithNoArgs.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001436 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001437 EXPECT_THAT(out, StrEq("stdout\n"));
1438 EXPECT_THAT(err, StrEq("stderr\n"));
1439}
1440
Felipe Lemef0292972016-11-22 13:57:05 -08001441TEST_F(DumpstateUtilTest, RunCommandWithTitle) {
1442 CreateFd("RunCommandWithNoArgs.txt");
1443 EXPECT_EQ(0, RunCommand("I AM GROOT", {kSimpleCommand}));
1444 EXPECT_THAT(out, StrEq("------ I AM GROOT (" + kSimpleCommand + ") ------\nstdout\n"));
1445 EXPECT_THAT(err, StrEq("stderr\n"));
1446}
1447
Felipe Leme46b85da2016-11-21 17:40:45 -08001448TEST_F(DumpstateUtilTest, RunCommandWithOneArg) {
1449 CreateFd("RunCommandWithOneArg.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001450 EXPECT_EQ(0, RunCommand("", {kEchoCommand, "one"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001451 EXPECT_THAT(err, IsEmpty());
1452 EXPECT_THAT(out, StrEq("one\n"));
1453}
1454
1455TEST_F(DumpstateUtilTest, RunCommandWithMultipleArgs) {
1456 CreateFd("RunCommandWithMultipleArgs.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001457 EXPECT_EQ(0, RunCommand("", {kEchoCommand, "one", "is", "the", "loniest", "number"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001458 EXPECT_THAT(err, IsEmpty());
1459 EXPECT_THAT(out, StrEq("one is the loniest number\n"));
1460}
1461
1462TEST_F(DumpstateUtilTest, RunCommandWithLoggingMessage) {
1463 CreateFd("RunCommandWithLoggingMessage.txt");
1464 EXPECT_EQ(
Felipe Lemef0292972016-11-22 13:57:05 -08001465 0, RunCommand("", {kSimpleCommand},
Felipe Leme46b85da2016-11-21 17:40:45 -08001466 CommandOptions::WithTimeout(10).Log("COMMAND, Y U NO LOG FIRST?").Build()));
1467 EXPECT_THAT(out, StrEq("stdout\n"));
1468 EXPECT_THAT(err, StrEq("COMMAND, Y U NO LOG FIRST?stderr\n"));
1469}
1470
1471TEST_F(DumpstateUtilTest, RunCommandRedirectStderr) {
1472 CreateFd("RunCommandRedirectStderr.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001473 EXPECT_EQ(0, RunCommand("", {kSimpleCommand},
1474 CommandOptions::WithTimeout(10).RedirectStderr().Build()));
Felipe Leme46b85da2016-11-21 17:40:45 -08001475 EXPECT_THAT(out, IsEmpty());
1476 EXPECT_THAT(err, StrEq("stdout\nstderr\n"));
1477}
1478
1479TEST_F(DumpstateUtilTest, RunCommandDryRun) {
1480 CreateFd("RunCommandDryRun.txt");
1481 SetDryRun(true);
Felipe Lemef0292972016-11-22 13:57:05 -08001482 EXPECT_EQ(0, RunCommand("I AM GROOT", {kSimpleCommand}));
1483 EXPECT_THAT(out, StrEq(android::base::StringPrintf(
1484 "------ I AM GROOT (%s) ------\n\t(skipped on dry run)\n",
1485 kSimpleCommand.c_str())));
1486 EXPECT_THAT(err, IsEmpty());
1487}
1488
1489TEST_F(DumpstateUtilTest, RunCommandDryRunNoTitle) {
1490 CreateFd("RunCommandDryRun.txt");
1491 SetDryRun(true);
1492 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001493 EXPECT_THAT(
1494 out, StrEq(android::base::StringPrintf("%s: skipped on dry run\n", kSimpleCommand.c_str())));
1495 EXPECT_THAT(err, IsEmpty());
1496}
1497
1498TEST_F(DumpstateUtilTest, RunCommandDryRunAlways) {
1499 CreateFd("RunCommandDryRunAlways.txt");
1500 SetDryRun(true);
Felipe Lemef0292972016-11-22 13:57:05 -08001501 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(10).Always().Build()));
Felipe Leme46b85da2016-11-21 17:40:45 -08001502 EXPECT_THAT(out, StrEq("stdout\n"));
1503 EXPECT_THAT(err, StrEq("stderr\n"));
1504}
1505
1506TEST_F(DumpstateUtilTest, RunCommandNotFound) {
1507 CreateFd("RunCommandNotFound.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001508 EXPECT_NE(0, RunCommand("", {"/there/cannot/be/such/command"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001509 EXPECT_THAT(out, StartsWith("*** command '/there/cannot/be/such/command' failed: exit code"));
1510 EXPECT_THAT(err, StartsWith("execvp on command '/there/cannot/be/such/command' failed"));
1511}
1512
1513TEST_F(DumpstateUtilTest, RunCommandFails) {
1514 CreateFd("RunCommandFails.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001515 EXPECT_EQ(42, RunCommand("", {kSimpleCommand, "--exit", "42"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001516 EXPECT_THAT(out, StrEq("stdout\n*** command '" + kSimpleCommand +
1517 " --exit 42' failed: exit code 42\n"));
1518 EXPECT_THAT(err, StrEq("stderr\n*** command '" + kSimpleCommand +
1519 " --exit 42' failed: exit code 42\n"));
1520}
1521
1522TEST_F(DumpstateUtilTest, RunCommandCrashes) {
1523 CreateFd("RunCommandCrashes.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001524 EXPECT_NE(0, RunCommand("", {kSimpleCommand, "--crash"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001525 // We don't know the exit code, so check just the prefix.
1526 EXPECT_THAT(
1527 out, StartsWith("stdout\n*** command '" + kSimpleCommand + " --crash' failed: exit code"));
1528 EXPECT_THAT(
1529 err, StartsWith("stderr\n*** command '" + kSimpleCommand + " --crash' failed: exit code"));
1530}
1531
Vishnu Nair6921f802017-11-22 09:17:23 -08001532TEST_F(DumpstateUtilTest, RunCommandTimesoutWithSec) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001533 CreateFd("RunCommandTimesout.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001534 EXPECT_EQ(-1, RunCommand("", {kSimpleCommand, "--sleep", "2"},
1535 CommandOptions::WithTimeout(1).Build()));
Felipe Leme46b85da2016-11-21 17:40:45 -08001536 EXPECT_THAT(out, StartsWith("stdout line1\n*** command '" + kSimpleCommand +
1537 " --sleep 2' timed out after 1"));
1538 EXPECT_THAT(err, StartsWith("sleeping for 2s\n*** command '" + kSimpleCommand +
1539 " --sleep 2' timed out after 1"));
1540}
1541
Vishnu Nair6921f802017-11-22 09:17:23 -08001542TEST_F(DumpstateUtilTest, RunCommandTimesoutWithMsec) {
1543 CreateFd("RunCommandTimesout.txt");
1544 EXPECT_EQ(-1, RunCommand("", {kSimpleCommand, "--sleep", "2"},
1545 CommandOptions::WithTimeoutInMs(1000).Build()));
1546 EXPECT_THAT(out, StartsWith("stdout line1\n*** command '" + kSimpleCommand +
1547 " --sleep 2' timed out after 1"));
1548 EXPECT_THAT(err, StartsWith("sleeping for 2s\n*** command '" + kSimpleCommand +
1549 " --sleep 2' timed out after 1"));
1550}
1551
1552
Felipe Leme46b85da2016-11-21 17:40:45 -08001553TEST_F(DumpstateUtilTest, RunCommandIsKilled) {
1554 CreateFd("RunCommandIsKilled.txt");
1555 CaptureStderr();
1556
1557 std::thread t([=]() {
Felipe Lemef0292972016-11-22 13:57:05 -08001558 EXPECT_EQ(SIGTERM, RunCommandToFd(fd, "", {kSimpleCommand, "--pid", "--sleep", "20"},
Felipe Leme46b85da2016-11-21 17:40:45 -08001559 CommandOptions::WithTimeout(100).Always().Build()));
1560 });
1561
1562 // Capture pid and pre-sleep output.
1563 sleep(1); // Wait a little bit to make sure pid and 1st line were printed.
1564 std::string err = GetCapturedStderr();
1565 EXPECT_THAT(err, StrEq("sleeping for 20s\n"));
1566
1567 CaptureFdOut();
1568 std::vector<std::string> lines = android::base::Split(out, "\n");
1569 ASSERT_EQ(3, (int)lines.size()) << "Invalid lines before sleep: " << out;
1570
1571 int pid = atoi(lines[0].c_str());
1572 EXPECT_THAT(lines[1], StrEq("stdout line1"));
1573 EXPECT_THAT(lines[2], IsEmpty()); // \n
1574
1575 // Then kill the process.
1576 CaptureFdOut();
1577 CaptureStderr();
1578 ASSERT_EQ(0, kill(pid, SIGTERM)) << "failed to kill pid " << pid;
1579 t.join();
1580
1581 // Finally, check output after murder.
1582 CaptureFdOut();
1583 err = GetCapturedStderr();
1584
1585 // out starts with the pid, which is an unknown
1586 EXPECT_THAT(out, EndsWith("stdout line1\n*** command '" + kSimpleCommand +
1587 " --pid --sleep 20' failed: killed by signal 15\n"));
1588 EXPECT_THAT(err, StrEq("*** command '" + kSimpleCommand +
1589 " --pid --sleep 20' failed: killed by signal 15\n"));
1590}
1591
1592TEST_F(DumpstateUtilTest, RunCommandAsRootUserBuild) {
1593 if (!IsStandalone()) {
1594 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1595 // to Shell - need to refactor tests to avoid this problem)
1596 MYLOGE("Skipping DumpstateUtilTest.RunCommandAsRootUserBuild() on test suite\n")
1597 return;
1598 }
1599 CreateFd("RunCommandAsRootUserBuild.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001600 if (!PropertiesHelper::IsUserBuild()) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001601 // Emulates user build if necessarily.
1602 SetBuildType("user");
1603 }
1604
1605 DropRoot();
1606
Felipe Lemef0292972016-11-22 13:57:05 -08001607 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).AsRoot().Build()));
Felipe Leme46b85da2016-11-21 17:40:45 -08001608
1609 // We don't know the exact path of su, so we just check for the 'root ...' commands
1610 EXPECT_THAT(out, StartsWith("Skipping"));
1611 EXPECT_THAT(out, EndsWith("root " + kSimpleCommand + "' on user build.\n"));
1612 EXPECT_THAT(err, IsEmpty());
1613}
1614
1615TEST_F(DumpstateUtilTest, RunCommandAsRootNonUserBuild) {
1616 if (!IsStandalone()) {
1617 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1618 // to Shell - need to refactor tests to avoid this problem)
1619 MYLOGE("Skipping DumpstateUtilTest.RunCommandAsRootNonUserBuild() on test suite\n")
1620 return;
1621 }
1622 CreateFd("RunCommandAsRootNonUserBuild.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001623 if (PropertiesHelper::IsUserBuild()) {
Felipe Leme7447d7c2016-11-03 18:12:22 -07001624 ALOGI("Skipping RunCommandAsRootNonUserBuild on user builds\n");
1625 return;
1626 }
1627
1628 DropRoot();
1629
Felipe Lemef0292972016-11-22 13:57:05 -08001630 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
1631 CommandOptions::WithTimeout(1).AsRoot().Build()));
Felipe Leme7447d7c2016-11-03 18:12:22 -07001632
1633 EXPECT_THAT(out, StrEq("0\nstdout\n"));
1634 EXPECT_THAT(err, StrEq("stderr\n"));
1635}
Felipe Leme46b85da2016-11-21 17:40:45 -08001636
Yifan Hong48e83a12017-10-03 14:10:07 -07001637
1638TEST_F(DumpstateUtilTest, RunCommandAsRootIfAvailableOnUserBuild) {
1639 if (!IsStandalone()) {
1640 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1641 // to Shell - need to refactor tests to avoid this problem)
1642 MYLOGE("Skipping DumpstateUtilTest.RunCommandAsRootIfAvailableOnUserBuild() on test suite\n")
1643 return;
1644 }
1645 CreateFd("RunCommandAsRootIfAvailableOnUserBuild.txt");
1646 if (!PropertiesHelper::IsUserBuild()) {
1647 // Emulates user build if necessarily.
1648 SetBuildType("user");
1649 }
1650
1651 DropRoot();
1652
1653 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
1654 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
1655
1656 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
1657 EXPECT_THAT(err, StrEq("stderr\n"));
1658}
1659
1660TEST_F(DumpstateUtilTest, RunCommandAsRootIfAvailableOnDebugBuild) {
1661 if (!IsStandalone()) {
1662 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1663 // to Shell - need to refactor tests to avoid this problem)
1664 MYLOGE("Skipping DumpstateUtilTest.RunCommandAsRootIfAvailableOnDebugBuild() on test suite\n")
1665 return;
1666 }
1667 CreateFd("RunCommandAsRootIfAvailableOnDebugBuild.txt");
1668 if (PropertiesHelper::IsUserBuild()) {
1669 ALOGI("Skipping RunCommandAsRootNonUserBuild on user builds\n");
1670 return;
1671 }
1672
1673 DropRoot();
1674
1675 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
1676 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
1677
1678 EXPECT_THAT(out, StrEq("0\nstdout\n"));
1679 EXPECT_THAT(err, StrEq("stderr\n"));
1680}
1681
Felipe Leme46b85da2016-11-21 17:40:45 -08001682TEST_F(DumpstateUtilTest, RunCommandDropRoot) {
1683 if (!IsStandalone()) {
1684 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1685 // to Shell - need to refactor tests to avoid this problem)
1686 MYLOGE("Skipping DumpstateUtilTest.RunCommandDropRoot() on test suite\n")
1687 return;
1688 }
1689 CreateFd("RunCommandDropRoot.txt");
1690 // First check root case - only available when running with 'adb root'.
1691 uid_t uid = getuid();
1692 if (uid == 0) {
Felipe Lemef0292972016-11-22 13:57:05 -08001693 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001694 EXPECT_THAT(out, StrEq("0\nstdout\n"));
1695 EXPECT_THAT(err, StrEq("stderr\n"));
1696 return;
1697 }
1698 // Then run dropping root.
Felipe Lemef0292972016-11-22 13:57:05 -08001699 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
Felipe Leme46b85da2016-11-21 17:40:45 -08001700 CommandOptions::WithTimeout(1).DropRoot().Build()));
1701 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
1702 EXPECT_THAT(err, StrEq("drop_root_user(): already running as Shell\nstderr\n"));
1703}
1704
Felipe Lemef0292972016-11-22 13:57:05 -08001705TEST_F(DumpstateUtilTest, DumpFileNotFoundNoTitle) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001706 CreateFd("DumpFileNotFound.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001707 EXPECT_EQ(-1, DumpFile("", "/I/cant/believe/I/exist"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001708 EXPECT_THAT(out,
1709 StrEq("*** Error dumping /I/cant/believe/I/exist: No such file or directory\n"));
1710 EXPECT_THAT(err, IsEmpty());
1711}
1712
Felipe Lemef0292972016-11-22 13:57:05 -08001713TEST_F(DumpstateUtilTest, DumpFileNotFoundWithTitle) {
1714 CreateFd("DumpFileNotFound.txt");
1715 EXPECT_EQ(-1, DumpFile("Y U NO EXIST?", "/I/cant/believe/I/exist"));
1716 EXPECT_THAT(out, StrEq("*** Error dumping /I/cant/believe/I/exist (Y U NO EXIST?): No such "
1717 "file or directory\n"));
1718 EXPECT_THAT(err, IsEmpty());
1719}
1720
Felipe Leme46b85da2016-11-21 17:40:45 -08001721TEST_F(DumpstateUtilTest, DumpFileSingleLine) {
1722 CreateFd("DumpFileSingleLine.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001723 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001724 EXPECT_THAT(err, IsEmpty());
1725 EXPECT_THAT(out, StrEq("I AM LINE1\n")); // dumpstate adds missing newline
1726}
1727
1728TEST_F(DumpstateUtilTest, DumpFileSingleLineWithNewLine) {
1729 CreateFd("DumpFileSingleLineWithNewLine.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001730 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line-with-newline.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001731 EXPECT_THAT(err, IsEmpty());
1732 EXPECT_THAT(out, StrEq("I AM LINE1\n"));
1733}
1734
1735TEST_F(DumpstateUtilTest, DumpFileMultipleLines) {
1736 CreateFd("DumpFileMultipleLines.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001737 EXPECT_EQ(0, DumpFile("", kTestDataPath + "multiple-lines.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001738 EXPECT_THAT(err, IsEmpty());
1739 EXPECT_THAT(out, StrEq("I AM LINE1\nI AM LINE2\nI AM LINE3\n"));
1740}
1741
1742TEST_F(DumpstateUtilTest, DumpFileMultipleLinesWithNewLine) {
1743 CreateFd("DumpFileMultipleLinesWithNewLine.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001744 EXPECT_EQ(0, DumpFile("", kTestDataPath + "multiple-lines-with-newline.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001745 EXPECT_THAT(err, IsEmpty());
1746 EXPECT_THAT(out, StrEq("I AM LINE1\nI AM LINE2\nI AM LINE3\n"));
1747}
1748
Felipe Lemef0292972016-11-22 13:57:05 -08001749TEST_F(DumpstateUtilTest, DumpFileOnDryRunNoTitle) {
1750 CreateFd("DumpFileOnDryRun.txt");
1751 SetDryRun(true);
1752 std::string path = kTestDataPath + "single-line.txt";
1753 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
1754 EXPECT_THAT(err, IsEmpty());
1755 EXPECT_THAT(out, StrEq(path + ": skipped on dry run\n"));
1756}
1757
Felipe Leme46b85da2016-11-21 17:40:45 -08001758TEST_F(DumpstateUtilTest, DumpFileOnDryRun) {
1759 CreateFd("DumpFileOnDryRun.txt");
1760 SetDryRun(true);
1761 std::string path = kTestDataPath + "single-line.txt";
Felipe Lemef0292972016-11-22 13:57:05 -08001762 EXPECT_EQ(0, DumpFile("Might as well dump. Dump!", kTestDataPath + "single-line.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001763 EXPECT_THAT(err, IsEmpty());
Felipe Lemef0292972016-11-22 13:57:05 -08001764 EXPECT_THAT(
1765 out, StartsWith("------ Might as well dump. Dump! (" + kTestDataPath + "single-line.txt:"));
1766 EXPECT_THAT(out, EndsWith("skipped on dry run\n"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001767}
Ecco Park61ffcf72016-10-27 15:46:26 -07001768
1769TEST_F(DumpstateUtilTest, FindingPidWithExistingProcess) {
1770 // init process always has pid 1.
1771 EXPECT_EQ(1, FindPidOfProcess("init"));
1772 EXPECT_THAT(err, IsEmpty());
1773}
1774
1775TEST_F(DumpstateUtilTest, FindingPidWithNotExistingProcess) {
1776 // find the process with abnormal name.
1777 EXPECT_EQ(-1, FindPidOfProcess("abcdef12345-543"));
1778 EXPECT_THAT(err, StrEq("can't find the pid\n"));
1779}
Felipe Leme47e9be22016-12-21 15:37:07 -08001780
1781} // namespace dumpstate
1782} // namespace os
1783} // namespace android