blob: cd9b97ff9d11103e7336fea84969cbd5658a7fc4 [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);
176 EXPECT_EQ("", options_.use_outfile);
177 EXPECT_FALSE(options_.use_socket);
178 EXPECT_FALSE(options_.use_control_socket);
179 EXPECT_FALSE(options_.show_header_only);
180 EXPECT_TRUE(options_.do_vibrate);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000181 EXPECT_FALSE(options_.do_fb);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100182 EXPECT_FALSE(options_.do_progress_updates);
183 EXPECT_FALSE(options_.is_remote_mode);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000184 EXPECT_FALSE(options_.do_broadcast);
185}
186
187TEST_F(DumpOptionsTest, InitializeAdbBugreport) {
188 // clang-format off
189 char* argv[] = {
190 const_cast<char*>("dumpstatez"),
191 const_cast<char*>("-S"),
192 const_cast<char*>("-d"),
193 const_cast<char*>("-z"),
194 const_cast<char*>("-o abc"),
195 };
196 // clang-format on
197
198 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
199
200 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
201 EXPECT_TRUE(options_.do_add_date);
202 EXPECT_TRUE(options_.do_zip_file);
203 EXPECT_TRUE(options_.use_control_socket);
204 EXPECT_EQ(" abc", std::string(options_.use_outfile));
205
206 // Other options retain default values
207 EXPECT_TRUE(options_.do_vibrate);
208 EXPECT_FALSE(options_.show_header_only);
209 EXPECT_FALSE(options_.do_fb);
210 EXPECT_FALSE(options_.do_progress_updates);
211 EXPECT_FALSE(options_.is_remote_mode);
212 EXPECT_FALSE(options_.do_broadcast);
213 EXPECT_FALSE(options_.use_socket);
214}
215
216TEST_F(DumpOptionsTest, InitializeAdbShellBugreport) {
217 // clang-format off
218 char* argv[] = {
219 const_cast<char*>("dumpstate"),
220 const_cast<char*>("-s"),
221 };
222 // clang-format on
223
224 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
225
226 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
227 EXPECT_TRUE(options_.use_socket);
228
229 // Other options retain default values
230 EXPECT_TRUE(options_.do_vibrate);
231 EXPECT_EQ("", options_.use_outfile);
232 EXPECT_FALSE(options_.do_add_date);
233 EXPECT_FALSE(options_.do_zip_file);
234 EXPECT_FALSE(options_.use_control_socket);
235 EXPECT_FALSE(options_.show_header_only);
236 EXPECT_FALSE(options_.do_fb);
237 EXPECT_FALSE(options_.do_progress_updates);
238 EXPECT_FALSE(options_.is_remote_mode);
239 EXPECT_FALSE(options_.do_broadcast);
240}
241
242TEST_F(DumpOptionsTest, InitializeFullBugReport) {
243 // clang-format off
244 char* argv[] = {
245 const_cast<char*>("bugreport"),
246 const_cast<char*>("-d"),
247 const_cast<char*>("-p"),
248 const_cast<char*>("-B"),
249 const_cast<char*>("-z"),
250 const_cast<char*>("-o abc"),
251 };
252 // clang-format on
253 property_set("dumpstate.options", "bugreportfull");
254
255 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
256
257 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
258 EXPECT_TRUE(options_.do_add_date);
259 EXPECT_TRUE(options_.do_fb);
260 EXPECT_TRUE(options_.do_zip_file);
Nandana Dutt58d72e22018-11-16 10:30:48 +0000261 EXPECT_TRUE(options_.do_broadcast);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000262 EXPECT_EQ(" abc", std::string(options_.use_outfile));
263
264 // Other options retain default values
265 EXPECT_TRUE(options_.do_vibrate);
266 EXPECT_FALSE(options_.use_control_socket);
267 EXPECT_FALSE(options_.show_header_only);
268 EXPECT_FALSE(options_.do_progress_updates);
269 EXPECT_FALSE(options_.is_remote_mode);
270 EXPECT_FALSE(options_.use_socket);
271 EXPECT_FALSE(options_.do_start_service);
272}
273
274TEST_F(DumpOptionsTest, InitializeInteractiveBugReport) {
275 // clang-format off
276 char* argv[] = {
277 const_cast<char*>("bugreport"),
278 const_cast<char*>("-d"),
279 const_cast<char*>("-p"),
280 const_cast<char*>("-B"),
281 const_cast<char*>("-z"),
282 const_cast<char*>("-o abc"),
283 };
284 // clang-format on
285
286 property_set("dumpstate.options", "bugreportplus");
287
288 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
289
290 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
291 EXPECT_TRUE(options_.do_add_date);
292 EXPECT_TRUE(options_.do_broadcast);
293 EXPECT_TRUE(options_.do_zip_file);
294 EXPECT_TRUE(options_.do_progress_updates);
295 EXPECT_TRUE(options_.do_start_service);
296 EXPECT_FALSE(options_.do_fb);
297 EXPECT_EQ(" abc", std::string(options_.use_outfile));
298
299 // Other options retain default values
300 EXPECT_TRUE(options_.do_vibrate);
301 EXPECT_FALSE(options_.use_control_socket);
302 EXPECT_FALSE(options_.show_header_only);
303 EXPECT_FALSE(options_.is_remote_mode);
304 EXPECT_FALSE(options_.use_socket);
305}
306
307TEST_F(DumpOptionsTest, InitializeRemoteBugReport) {
308 // clang-format off
309 char* argv[] = {
310 const_cast<char*>("bugreport"),
311 const_cast<char*>("-d"),
312 const_cast<char*>("-p"),
313 const_cast<char*>("-B"),
314 const_cast<char*>("-z"),
315 const_cast<char*>("-o abc"),
316 };
317 // clang-format on
318
319 property_set("dumpstate.options", "bugreportremote");
320
321 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
322
323 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
324 EXPECT_TRUE(options_.do_add_date);
325 EXPECT_TRUE(options_.do_broadcast);
326 EXPECT_TRUE(options_.do_zip_file);
327 EXPECT_TRUE(options_.is_remote_mode);
328 EXPECT_FALSE(options_.do_vibrate);
329 EXPECT_FALSE(options_.do_fb);
330 EXPECT_EQ(" abc", std::string(options_.use_outfile));
331
332 // Other options retain default values
333 EXPECT_FALSE(options_.use_control_socket);
334 EXPECT_FALSE(options_.show_header_only);
335 EXPECT_FALSE(options_.do_progress_updates);
336 EXPECT_FALSE(options_.use_socket);
337}
338
339TEST_F(DumpOptionsTest, InitializeWearBugReport) {
340 // clang-format off
341 char* argv[] = {
342 const_cast<char*>("bugreport"),
343 const_cast<char*>("-d"),
344 const_cast<char*>("-p"),
345 const_cast<char*>("-B"),
346 const_cast<char*>("-z"),
347 const_cast<char*>("-o abc"),
348 };
349 // clang-format on
350
351 property_set("dumpstate.options", "bugreportwear");
352
353 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
354
355 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
356 EXPECT_TRUE(options_.do_add_date);
357 EXPECT_TRUE(options_.do_fb);
358 EXPECT_TRUE(options_.do_broadcast);
359 EXPECT_TRUE(options_.do_zip_file);
360 EXPECT_TRUE(options_.do_progress_updates);
361 EXPECT_TRUE(options_.do_start_service);
362 EXPECT_EQ(" abc", std::string(options_.use_outfile));
363
364 // Other options retain default values
365 EXPECT_TRUE(options_.do_vibrate);
366 EXPECT_FALSE(options_.use_control_socket);
367 EXPECT_FALSE(options_.show_header_only);
368 EXPECT_FALSE(options_.is_remote_mode);
369 EXPECT_FALSE(options_.use_socket);
370}
371
372TEST_F(DumpOptionsTest, InitializeTelephonyBugReport) {
373 // clang-format off
374 char* argv[] = {
375 const_cast<char*>("bugreport"),
376 const_cast<char*>("-d"),
377 const_cast<char*>("-p"),
378 const_cast<char*>("-B"),
379 const_cast<char*>("-z"),
380 const_cast<char*>("-o abc"),
381 };
382 // clang-format on
383
384 property_set("dumpstate.options", "bugreporttelephony");
385
386 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
387
388 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
389 EXPECT_TRUE(options_.do_add_date);
390 EXPECT_TRUE(options_.do_fb);
391 EXPECT_TRUE(options_.do_broadcast);
392 EXPECT_TRUE(options_.do_zip_file);
393 EXPECT_TRUE(options_.telephony_only);
394 EXPECT_EQ(" abc", std::string(options_.use_outfile));
395
396 // Other options retain default values
397 EXPECT_TRUE(options_.do_vibrate);
398 EXPECT_FALSE(options_.use_control_socket);
399 EXPECT_FALSE(options_.show_header_only);
400 EXPECT_FALSE(options_.do_progress_updates);
401 EXPECT_FALSE(options_.is_remote_mode);
402 EXPECT_FALSE(options_.use_socket);
403}
404
405TEST_F(DumpOptionsTest, InitializeWifiBugReport) {
406 // clang-format off
407 char* argv[] = {
408 const_cast<char*>("bugreport"),
409 const_cast<char*>("-d"),
410 const_cast<char*>("-p"),
411 const_cast<char*>("-B"),
412 const_cast<char*>("-z"),
413 const_cast<char*>("-o abc"),
414 };
415 // clang-format on
416
417 property_set("dumpstate.options", "bugreportwifi");
418
419 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
420
421 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
422 EXPECT_TRUE(options_.do_add_date);
423 EXPECT_TRUE(options_.do_fb);
424 EXPECT_TRUE(options_.do_broadcast);
425 EXPECT_TRUE(options_.do_zip_file);
426 EXPECT_TRUE(options_.wifi_only);
427 EXPECT_EQ(" abc", std::string(options_.use_outfile));
428
429 // Other options retain default values
430 EXPECT_TRUE(options_.do_vibrate);
431 EXPECT_FALSE(options_.use_control_socket);
432 EXPECT_FALSE(options_.show_header_only);
433 EXPECT_FALSE(options_.do_progress_updates);
434 EXPECT_FALSE(options_.is_remote_mode);
435 EXPECT_FALSE(options_.use_socket);
436}
437
438TEST_F(DumpOptionsTest, InitializeDefaultBugReport) {
439 // default: commandline options are not overridden
440 // clang-format off
441 char* argv[] = {
442 const_cast<char*>("bugreport"),
443 const_cast<char*>("-d"),
444 const_cast<char*>("-p"),
445 const_cast<char*>("-B"),
446 const_cast<char*>("-z"),
447 const_cast<char*>("-o abc"),
448 };
449 // clang-format on
450
451 property_set("dumpstate.options", "");
452
453 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
454
455 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
456 EXPECT_TRUE(options_.do_add_date);
457 EXPECT_TRUE(options_.do_fb);
458 EXPECT_TRUE(options_.do_zip_file);
459 EXPECT_TRUE(options_.do_broadcast);
460 EXPECT_EQ(" abc", std::string(options_.use_outfile));
461
462 // Other options retain default values
463 EXPECT_TRUE(options_.do_vibrate);
464 EXPECT_FALSE(options_.use_control_socket);
465 EXPECT_FALSE(options_.show_header_only);
466 EXPECT_FALSE(options_.do_progress_updates);
467 EXPECT_FALSE(options_.is_remote_mode);
468 EXPECT_FALSE(options_.use_socket);
469 EXPECT_FALSE(options_.wifi_only);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100470}
471
472TEST_F(DumpOptionsTest, InitializePartial1) {
473 // clang-format off
474 char* argv[] = {
475 const_cast<char*>("dumpstate"),
476 const_cast<char*>("-d"),
477 const_cast<char*>("-z"),
478 const_cast<char*>("-o abc"),
479 const_cast<char*>("-s"),
480 const_cast<char*>("-S"),
481
482 };
483 // clang-format on
484
485 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
486
487 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
488 EXPECT_TRUE(options_.do_add_date);
489 EXPECT_TRUE(options_.do_zip_file);
490 // TODO: Maybe we should trim the filename
491 EXPECT_EQ(" abc", std::string(options_.use_outfile));
492 EXPECT_TRUE(options_.use_socket);
493 EXPECT_TRUE(options_.use_control_socket);
494
495 // Other options retain default values
496 EXPECT_FALSE(options_.show_header_only);
497 EXPECT_TRUE(options_.do_vibrate);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000498 EXPECT_FALSE(options_.do_fb);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100499 EXPECT_FALSE(options_.do_progress_updates);
500 EXPECT_FALSE(options_.is_remote_mode);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000501 EXPECT_FALSE(options_.do_broadcast);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100502}
503
504TEST_F(DumpOptionsTest, InitializePartial2) {
505 // clang-format off
506 char* argv[] = {
507 const_cast<char*>("dumpstate"),
508 const_cast<char*>("-v"),
509 const_cast<char*>("-q"),
510 const_cast<char*>("-p"),
511 const_cast<char*>("-P"),
512 const_cast<char*>("-R"),
513 const_cast<char*>("-B"),
514 };
515 // clang-format on
516
517 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
518
519 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
520 EXPECT_TRUE(options_.show_header_only);
521 EXPECT_FALSE(options_.do_vibrate);
522 EXPECT_TRUE(options_.do_fb);
523 EXPECT_TRUE(options_.do_progress_updates);
524 EXPECT_TRUE(options_.is_remote_mode);
525 EXPECT_TRUE(options_.do_broadcast);
526
527 // Other options retain default values
528 EXPECT_FALSE(options_.do_add_date);
529 EXPECT_FALSE(options_.do_zip_file);
530 EXPECT_EQ("", options_.use_outfile);
531 EXPECT_FALSE(options_.use_socket);
532 EXPECT_FALSE(options_.use_control_socket);
533}
534
535TEST_F(DumpOptionsTest, InitializeHelp) {
536 // clang-format off
537 char* argv[] = {
538 const_cast<char*>("dumpstate"),
539 const_cast<char*>("-h")
540 };
541 // clang-format on
542
543 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
544
545 // -h is for help.
546 EXPECT_EQ(status, Dumpstate::RunStatus::HELP);
547}
548
549TEST_F(DumpOptionsTest, InitializeUnknown) {
550 // clang-format off
551 char* argv[] = {
552 const_cast<char*>("dumpstate"),
553 const_cast<char*>("-u") // unknown flag
554 };
555 // clang-format on
556
557 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
558
559 // -u is unknown.
560 EXPECT_EQ(status, Dumpstate::RunStatus::INVALID_INPUT);
561}
562
563TEST_F(DumpOptionsTest, ValidateOptionsNeedOutfile1) {
564 options_.do_zip_file = true;
565 EXPECT_FALSE(options_.ValidateOptions());
566 options_.use_outfile = "a/b/c";
567 EXPECT_TRUE(options_.ValidateOptions());
568}
569
570TEST_F(DumpOptionsTest, ValidateOptionsNeedOutfile2) {
571 options_.do_broadcast = true;
572 EXPECT_FALSE(options_.ValidateOptions());
573 options_.use_outfile = "a/b/c";
574 EXPECT_TRUE(options_.ValidateOptions());
575}
576
577TEST_F(DumpOptionsTest, ValidateOptionsNeedZipfile) {
578 options_.use_control_socket = true;
579 EXPECT_FALSE(options_.ValidateOptions());
580
581 options_.do_zip_file = true;
582 options_.use_outfile = "a/b/c"; // do_zip_file needs outfile
583 EXPECT_TRUE(options_.ValidateOptions());
584}
585
586TEST_F(DumpOptionsTest, ValidateOptionsUpdateProgressNeedsBroadcast) {
587 options_.do_progress_updates = true;
588 options_.use_outfile = "a/b/c"; // do_progress_updates needs outfile
589 EXPECT_FALSE(options_.ValidateOptions());
590
591 options_.do_broadcast = true;
592 EXPECT_TRUE(options_.ValidateOptions());
593}
594
595TEST_F(DumpOptionsTest, ValidateOptionsRemoteMode) {
596 options_.is_remote_mode = true;
597 EXPECT_FALSE(options_.ValidateOptions());
598
599 options_.do_broadcast = true;
600 options_.do_zip_file = true;
601 options_.do_add_date = true;
602 options_.use_outfile = "a/b/c"; // do_broadcast needs outfile
603 EXPECT_TRUE(options_.ValidateOptions());
604}
605
Felipe Leme7447d7c2016-11-03 18:12:22 -0700606class DumpstateTest : public DumpstateBaseTest {
Felipe Leme4c2d6632016-09-28 14:32:00 -0700607 public:
608 void SetUp() {
Felipe Leme46b85da2016-11-21 17:40:45 -0800609 DumpstateBaseTest::SetUp();
Felipe Leme4c2d6632016-09-28 14:32:00 -0700610 SetDryRun(false);
Felipe Lemed80e6b62016-10-03 13:08:14 -0700611 SetBuildType(android::base::GetProperty("ro.build.type", "(unknown)"));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700612 ds.progress_.reset(new Progress());
Felipe Leme009ecbb2016-11-07 10:18:44 -0800613 ds.update_progress_threshold_ = 0;
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100614 ds.options_.reset(new Dumpstate::DumpOptions());
Felipe Leme4c2d6632016-09-28 14:32:00 -0700615 }
616
617 // Runs a command and capture `stdout` and `stderr`.
Felipe Leme9a523ae2016-10-20 15:10:33 -0700618 int RunCommand(const std::string& title, const std::vector<std::string>& full_command,
Felipe Leme4c2d6632016-09-28 14:32:00 -0700619 const CommandOptions& options = CommandOptions::DEFAULT) {
620 CaptureStdout();
621 CaptureStderr();
Felipe Leme9a523ae2016-10-20 15:10:33 -0700622 int status = ds.RunCommand(title, full_command, options);
Felipe Leme4c2d6632016-09-28 14:32:00 -0700623 out = GetCapturedStdout();
624 err = GetCapturedStderr();
625 return status;
626 }
627
Felipe Lemecef02982016-10-03 17:22:22 -0700628 // Dumps a file and capture `stdout` and `stderr`.
629 int DumpFile(const std::string& title, const std::string& path) {
630 CaptureStdout();
631 CaptureStderr();
632 int status = ds.DumpFile(title, path);
633 out = GetCapturedStdout();
634 err = GetCapturedStderr();
635 return status;
636 }
637
Felipe Leme009ecbb2016-11-07 10:18:44 -0800638 void SetProgress(long progress, long initial_max, long threshold = 0) {
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100639 ds.options_->do_progress_updates = true;
Felipe Leme009ecbb2016-11-07 10:18:44 -0800640 ds.update_progress_threshold_ = threshold;
641 ds.last_updated_progress_ = 0;
Felipe Leme7447d7c2016-11-03 18:12:22 -0700642 ds.progress_.reset(new Progress(initial_max, progress, 1.2));
643 }
644
Felipe Leme7447d7c2016-11-03 18:12:22 -0700645 std::string GetProgressMessage(const std::string& listener_name, int progress, int max,
Felipe Leme009ecbb2016-11-07 10:18:44 -0800646 int old_max = 0, bool update_progress = true) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700647 EXPECT_EQ(progress, ds.progress_->Get()) << "invalid progress";
648 EXPECT_EQ(max, ds.progress_->GetMax()) << "invalid max";
Felipe Leme75876a22016-10-27 16:31:27 -0700649
Felipe Leme7447d7c2016-11-03 18:12:22 -0700650 bool max_increased = old_max > 0;
Felipe Leme75876a22016-10-27 16:31:27 -0700651
Felipe Leme009ecbb2016-11-07 10:18:44 -0800652 std::string message = "";
Felipe Leme75876a22016-10-27 16:31:27 -0700653 if (max_increased) {
Felipe Leme009ecbb2016-11-07 10:18:44 -0800654 message =
Felipe Leme7447d7c2016-11-03 18:12:22 -0700655 android::base::StringPrintf("Adjusting max progress from %d to %d\n", old_max, max);
Felipe Leme75876a22016-10-27 16:31:27 -0700656 }
657
Felipe Leme009ecbb2016-11-07 10:18:44 -0800658 if (update_progress) {
Nandana Duttbabf6c72019-01-15 14:11:12 +0000659 message += android::base::StringPrintf("Setting progress (%s): %d/%d (%d%%)\n",
660 listener_name.c_str(), progress, max,
661 (100 * progress / max));
Felipe Leme009ecbb2016-11-07 10:18:44 -0800662 }
663
664 return message;
Felipe Lemed80e6b62016-10-03 13:08:14 -0700665 }
666
Felipe Leme4c2d6632016-09-28 14:32:00 -0700667 // `stdout` and `stderr` from the last command ran.
668 std::string out, err;
669
Felipe Lemefd8affa2016-09-30 17:38:57 -0700670 Dumpstate& ds = Dumpstate::GetInstance();
Felipe Leme4c2d6632016-09-28 14:32:00 -0700671};
672
673TEST_F(DumpstateTest, RunCommandNoArgs) {
674 EXPECT_EQ(-1, RunCommand("", {}));
675}
676
677TEST_F(DumpstateTest, RunCommandNoTitle) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700678 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700679 EXPECT_THAT(out, StrEq("stdout\n"));
680 EXPECT_THAT(err, StrEq("stderr\n"));
681}
682
683TEST_F(DumpstateTest, RunCommandWithTitle) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700684 EXPECT_EQ(0, RunCommand("I AM GROOT", {kSimpleCommand}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700685 EXPECT_THAT(err, StrEq("stderr\n"));
686 // We don't know the exact duration, so we check the prefix and suffix
Felipe Lemefd8affa2016-09-30 17:38:57 -0700687 EXPECT_THAT(out,
Felipe Leme7447d7c2016-11-03 18:12:22 -0700688 StartsWith("------ I AM GROOT (" + kSimpleCommand + ") ------\nstdout\n------"));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700689 EXPECT_THAT(out, EndsWith("s was the duration of 'I AM GROOT' ------\n"));
690}
691
Felipe Lemefd8affa2016-09-30 17:38:57 -0700692TEST_F(DumpstateTest, RunCommandWithLoggingMessage) {
Felipe Leme4c2d6632016-09-28 14:32:00 -0700693 EXPECT_EQ(
Felipe Leme7447d7c2016-11-03 18:12:22 -0700694 0, RunCommand("", {kSimpleCommand},
Felipe Lemefd8affa2016-09-30 17:38:57 -0700695 CommandOptions::WithTimeout(10).Log("COMMAND, Y U NO LOG FIRST?").Build()));
696 EXPECT_THAT(out, StrEq("stdout\n"));
697 EXPECT_THAT(err, StrEq("COMMAND, Y U NO LOG FIRST?stderr\n"));
698}
699
700TEST_F(DumpstateTest, RunCommandRedirectStderr) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700701 EXPECT_EQ(0, RunCommand("", {kSimpleCommand},
Felipe Lemefd8affa2016-09-30 17:38:57 -0700702 CommandOptions::WithTimeout(10).RedirectStderr().Build()));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700703 EXPECT_THAT(out, IsEmpty());
Felipe Lemefd8affa2016-09-30 17:38:57 -0700704 EXPECT_THAT(err, StrEq("stdout\nstderr\n"));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700705}
706
707TEST_F(DumpstateTest, RunCommandWithOneArg) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700708 EXPECT_EQ(0, RunCommand("", {kEchoCommand, "one"}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700709 EXPECT_THAT(err, IsEmpty());
710 EXPECT_THAT(out, StrEq("one\n"));
711}
712
Felipe Lemefd8affa2016-09-30 17:38:57 -0700713TEST_F(DumpstateTest, RunCommandWithMultipleArgs) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700714 EXPECT_EQ(0, RunCommand("", {kEchoCommand, "one", "is", "the", "loniest", "number"}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700715 EXPECT_THAT(err, IsEmpty());
716 EXPECT_THAT(out, StrEq("one is the loniest number\n"));
717}
718
719TEST_F(DumpstateTest, RunCommandDryRun) {
720 SetDryRun(true);
Felipe Leme7447d7c2016-11-03 18:12:22 -0700721 EXPECT_EQ(0, RunCommand("I AM GROOT", {kSimpleCommand}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700722 // We don't know the exact duration, so we check the prefix and suffix
Felipe Leme7447d7c2016-11-03 18:12:22 -0700723 EXPECT_THAT(out, StartsWith("------ I AM GROOT (" + kSimpleCommand +
Felipe Leme4c2d6632016-09-28 14:32:00 -0700724 ") ------\n\t(skipped on dry run)\n------"));
725 EXPECT_THAT(out, EndsWith("s was the duration of 'I AM GROOT' ------\n"));
726 EXPECT_THAT(err, IsEmpty());
727}
728
729TEST_F(DumpstateTest, RunCommandDryRunNoTitle) {
730 SetDryRun(true);
Felipe Leme7447d7c2016-11-03 18:12:22 -0700731 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700732 EXPECT_THAT(out, IsEmpty());
733 EXPECT_THAT(err, IsEmpty());
734}
735
736TEST_F(DumpstateTest, RunCommandDryRunAlways) {
737 SetDryRun(true);
Felipe Leme7447d7c2016-11-03 18:12:22 -0700738 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(10).Always().Build()));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700739 EXPECT_THAT(out, StrEq("stdout\n"));
740 EXPECT_THAT(err, StrEq("stderr\n"));
741}
742
Felipe Lemefd8affa2016-09-30 17:38:57 -0700743TEST_F(DumpstateTest, RunCommandNotFound) {
744 EXPECT_NE(0, RunCommand("", {"/there/cannot/be/such/command"}));
745 EXPECT_THAT(out, StartsWith("*** command '/there/cannot/be/such/command' failed: exit code"));
746 EXPECT_THAT(err, StartsWith("execvp on command '/there/cannot/be/such/command' failed"));
747}
748
749TEST_F(DumpstateTest, RunCommandFails) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700750 EXPECT_EQ(42, RunCommand("", {kSimpleCommand, "--exit", "42"}));
751 EXPECT_THAT(out, StrEq("stdout\n*** command '" + kSimpleCommand +
Felipe Leme9a523ae2016-10-20 15:10:33 -0700752 " --exit 42' failed: exit code 42\n"));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700753 EXPECT_THAT(err, StrEq("stderr\n*** command '" + kSimpleCommand +
Felipe Leme9a523ae2016-10-20 15:10:33 -0700754 " --exit 42' failed: exit code 42\n"));
Felipe Lemefd8affa2016-09-30 17:38:57 -0700755}
756
757TEST_F(DumpstateTest, RunCommandCrashes) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700758 EXPECT_NE(0, RunCommand("", {kSimpleCommand, "--crash"}));
Felipe Lemefd8affa2016-09-30 17:38:57 -0700759 // We don't know the exit code, so check just the prefix.
760 EXPECT_THAT(
Felipe Leme7447d7c2016-11-03 18:12:22 -0700761 out, StartsWith("stdout\n*** command '" + kSimpleCommand + " --crash' failed: exit code"));
Felipe Lemefd8affa2016-09-30 17:38:57 -0700762 EXPECT_THAT(
Felipe Leme7447d7c2016-11-03 18:12:22 -0700763 err, StartsWith("stderr\n*** command '" + kSimpleCommand + " --crash' failed: exit code"));
Felipe Lemefd8affa2016-09-30 17:38:57 -0700764}
765
766TEST_F(DumpstateTest, RunCommandTimesout) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700767 EXPECT_EQ(-1, RunCommand("", {kSimpleCommand, "--sleep", "2"},
Felipe Lemefd8affa2016-09-30 17:38:57 -0700768 CommandOptions::WithTimeout(1).Build()));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700769 EXPECT_THAT(out, StartsWith("stdout line1\n*** command '" + kSimpleCommand +
Felipe Lemefd8affa2016-09-30 17:38:57 -0700770 " --sleep 2' timed out after 1"));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700771 EXPECT_THAT(err, StartsWith("sleeping for 2s\n*** command '" + kSimpleCommand +
Felipe Lemefd8affa2016-09-30 17:38:57 -0700772 " --sleep 2' timed out after 1"));
773}
774
775TEST_F(DumpstateTest, RunCommandIsKilled) {
776 CaptureStdout();
777 CaptureStderr();
778
779 std::thread t([=]() {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700780 EXPECT_EQ(SIGTERM, ds.RunCommand("", {kSimpleCommand, "--pid", "--sleep", "20"},
Felipe Lemefd8affa2016-09-30 17:38:57 -0700781 CommandOptions::WithTimeout(100).Always().Build()));
782 });
783
784 // Capture pid and pre-sleep output.
785 sleep(1); // Wait a little bit to make sure pid and 1st line were printed.
786 std::string err = GetCapturedStderr();
787 EXPECT_THAT(err, StrEq("sleeping for 20s\n"));
788
789 std::string out = GetCapturedStdout();
790 std::vector<std::string> lines = android::base::Split(out, "\n");
791 ASSERT_EQ(3, (int)lines.size()) << "Invalid lines before sleep: " << out;
792
793 int pid = atoi(lines[0].c_str());
794 EXPECT_THAT(lines[1], StrEq("stdout line1"));
795 EXPECT_THAT(lines[2], IsEmpty()); // \n
796
797 // Then kill the process.
798 CaptureStdout();
799 CaptureStderr();
800 ASSERT_EQ(0, kill(pid, SIGTERM)) << "failed to kill pid " << pid;
801 t.join();
802
803 // Finally, check output after murder.
804 out = GetCapturedStdout();
805 err = GetCapturedStderr();
806
Felipe Leme7447d7c2016-11-03 18:12:22 -0700807 EXPECT_THAT(out, StrEq("*** command '" + kSimpleCommand +
Felipe Lemefd8affa2016-09-30 17:38:57 -0700808 " --pid --sleep 20' failed: killed by signal 15\n"));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700809 EXPECT_THAT(err, StrEq("*** command '" + kSimpleCommand +
Felipe Lemefd8affa2016-09-30 17:38:57 -0700810 " --pid --sleep 20' failed: killed by signal 15\n"));
811}
812
Felipe Leme75876a22016-10-27 16:31:27 -0700813TEST_F(DumpstateTest, RunCommandProgress) {
814 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
815 ds.listener_ = listener;
816 ds.listener_name_ = "FoxMulder";
Felipe Leme7447d7c2016-11-03 18:12:22 -0700817 SetProgress(0, 30);
Felipe Leme75876a22016-10-27 16:31:27 -0700818
819 EXPECT_CALL(*listener, onProgressUpdated(20));
Nandana Duttbabf6c72019-01-15 14:11:12 +0000820 EXPECT_CALL(*listener, onProgress(66)); // 20/30 %
Felipe Leme7447d7c2016-11-03 18:12:22 -0700821 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(20).Build()));
Felipe Leme75876a22016-10-27 16:31:27 -0700822 std::string progress_message = GetProgressMessage(ds.listener_name_, 20, 30);
823 EXPECT_THAT(out, StrEq("stdout\n"));
824 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
825
826 EXPECT_CALL(*listener, onProgressUpdated(30));
Nandana Duttbabf6c72019-01-15 14:11:12 +0000827 EXPECT_CALL(*listener, onProgress(100)); // 35/35 %
Felipe Leme7447d7c2016-11-03 18:12:22 -0700828 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(10).Build()));
Felipe Leme75876a22016-10-27 16:31:27 -0700829 progress_message = GetProgressMessage(ds.listener_name_, 30, 30);
830 EXPECT_THAT(out, StrEq("stdout\n"));
831 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
832
833 // Run a command that will increase maximum timeout.
834 EXPECT_CALL(*listener, onProgressUpdated(31));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700835 EXPECT_CALL(*listener, onMaxProgressUpdated(37));
Nandana Duttbabf6c72019-01-15 14:11:12 +0000836 EXPECT_CALL(*listener, onProgress(83)); // 31/37 %
Felipe Leme7447d7c2016-11-03 18:12:22 -0700837 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).Build()));
838 progress_message = GetProgressMessage(ds.listener_name_, 31, 37, 30); // 20% increase
Felipe Leme75876a22016-10-27 16:31:27 -0700839 EXPECT_THAT(out, StrEq("stdout\n"));
840 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
841
842 // Make sure command ran while in dry_run is counted.
843 SetDryRun(true);
844 EXPECT_CALL(*listener, onProgressUpdated(35));
Nandana Duttbabf6c72019-01-15 14:11:12 +0000845 EXPECT_CALL(*listener, onProgress(94)); // 35/37 %
Felipe Leme7447d7c2016-11-03 18:12:22 -0700846 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(4).Build()));
847 progress_message = GetProgressMessage(ds.listener_name_, 35, 37);
Felipe Leme75876a22016-10-27 16:31:27 -0700848 EXPECT_THAT(out, IsEmpty());
849 EXPECT_THAT(err, StrEq(progress_message));
850
851 ds.listener_.clear();
852}
853
Felipe Leme009ecbb2016-11-07 10:18:44 -0800854TEST_F(DumpstateTest, RunCommandProgressIgnoreThreshold) {
855 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
856 ds.listener_ = listener;
857 ds.listener_name_ = "FoxMulder";
858 SetProgress(0, 8, 5); // 8 max, 5 threshold
859
860 // First update should always be sent.
861 EXPECT_CALL(*listener, onProgressUpdated(1));
Nandana Duttbabf6c72019-01-15 14:11:12 +0000862 EXPECT_CALL(*listener, onProgress(12)); // 1/12 %
Felipe Leme009ecbb2016-11-07 10:18:44 -0800863 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).Build()));
864 std::string progress_message = GetProgressMessage(ds.listener_name_, 1, 8);
865 EXPECT_THAT(out, StrEq("stdout\n"));
866 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
867
868 // Fourth update should be ignored because it's between the threshold (5 -1 = 4 < 5).
869 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(4).Build()));
870 EXPECT_THAT(out, StrEq("stdout\n"));
871 EXPECT_THAT(err, StrEq("stderr\n"));
872
873 // Third update should be sent because it reaches threshold (6 - 1 = 5).
874 EXPECT_CALL(*listener, onProgressUpdated(6));
Nandana Duttbabf6c72019-01-15 14:11:12 +0000875 EXPECT_CALL(*listener, onProgress(75)); // 6/8 %
Felipe Leme009ecbb2016-11-07 10:18:44 -0800876 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).Build()));
877 progress_message = GetProgressMessage(ds.listener_name_, 6, 8);
878 EXPECT_THAT(out, StrEq("stdout\n"));
879 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
880
881 // Fourth update should be ignored because it's between the threshold (9 - 6 = 3 < 5).
882 // But max update should be sent.
883 EXPECT_CALL(*listener, onMaxProgressUpdated(10)); // 9 * 120% = 10.8 = 10
884 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(3).Build()));
885 progress_message = GetProgressMessage(ds.listener_name_, 9, 10, 8, false);
886 EXPECT_THAT(out, StrEq("stdout\n"));
887 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
888
889 ds.listener_.clear();
890}
891
Felipe Lemed80e6b62016-10-03 13:08:14 -0700892TEST_F(DumpstateTest, RunCommandDropRoot) {
Felipe Leme46b85da2016-11-21 17:40:45 -0800893 if (!IsStandalone()) {
894 // TODO: temporarily disabled because it might cause other tests to fail after dropping
895 // to Shell - need to refactor tests to avoid this problem)
896 MYLOGE("Skipping DumpstateTest.RunCommandDropRoot() on test suite\n")
897 return;
898 }
Felipe Lemed80e6b62016-10-03 13:08:14 -0700899 // First check root case - only available when running with 'adb root'.
900 uid_t uid = getuid();
901 if (uid == 0) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700902 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"}));
Felipe Lemed80e6b62016-10-03 13:08:14 -0700903 EXPECT_THAT(out, StrEq("0\nstdout\n"));
904 EXPECT_THAT(err, StrEq("stderr\n"));
905 return;
906 }
Felipe Leme7447d7c2016-11-03 18:12:22 -0700907 // Then run dropping root.
908 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
Felipe Lemed80e6b62016-10-03 13:08:14 -0700909 CommandOptions::WithTimeout(1).DropRoot().Build()));
910 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
Felipe Leme26c41572016-10-06 14:34:43 -0700911 EXPECT_THAT(err, StrEq("drop_root_user(): already running as Shell\nstderr\n"));
Felipe Lemed80e6b62016-10-03 13:08:14 -0700912}
913
914TEST_F(DumpstateTest, RunCommandAsRootUserBuild) {
Felipe Leme46b85da2016-11-21 17:40:45 -0800915 if (!IsStandalone()) {
916 // TODO: temporarily disabled because it might cause other tests to fail after dropping
917 // to Shell - need to refactor tests to avoid this problem)
918 MYLOGE("Skipping DumpstateTest.RunCommandAsRootUserBuild() on test suite\n")
919 return;
920 }
Felipe Lemef0292972016-11-22 13:57:05 -0800921 if (!PropertiesHelper::IsUserBuild()) {
Felipe Lemed80e6b62016-10-03 13:08:14 -0700922 // Emulates user build if necessarily.
923 SetBuildType("user");
924 }
925
926 DropRoot();
927
Felipe Leme7447d7c2016-11-03 18:12:22 -0700928 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).AsRoot().Build()));
Felipe Lemed80e6b62016-10-03 13:08:14 -0700929
930 // We don't know the exact path of su, so we just check for the 'root ...' commands
931 EXPECT_THAT(out, StartsWith("Skipping"));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700932 EXPECT_THAT(out, EndsWith("root " + kSimpleCommand + "' on user build.\n"));
Felipe Lemed80e6b62016-10-03 13:08:14 -0700933 EXPECT_THAT(err, IsEmpty());
934}
935
Felipe Leme46b85da2016-11-21 17:40:45 -0800936TEST_F(DumpstateTest, RunCommandAsRootNonUserBuild) {
937 if (!IsStandalone()) {
938 // TODO: temporarily disabled because it might cause other tests to fail after dropping
939 // to Shell - need to refactor tests to avoid this problem)
940 MYLOGE("Skipping DumpstateTest.RunCommandAsRootNonUserBuild() on test suite\n")
941 return;
942 }
Felipe Lemef0292972016-11-22 13:57:05 -0800943 if (PropertiesHelper::IsUserBuild()) {
Felipe Leme46b85da2016-11-21 17:40:45 -0800944 ALOGI("Skipping RunCommandAsRootNonUserBuild on user builds\n");
945 return;
946 }
947
948 DropRoot();
949
950 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
951 CommandOptions::WithTimeout(1).AsRoot().Build()));
952
953 EXPECT_THAT(out, StrEq("0\nstdout\n"));
954 EXPECT_THAT(err, StrEq("stderr\n"));
955}
956
Nandana Dutt4b392be2018-11-02 16:17:05 +0000957TEST_F(DumpstateTest, RunCommandAsRootNonUserBuild_withUnroot) {
958 if (!IsStandalone()) {
959 // TODO: temporarily disabled because it might cause other tests to fail after dropping
960 // to Shell - need to refactor tests to avoid this problem)
961 MYLOGE(
962 "Skipping DumpstateTest.RunCommandAsRootNonUserBuild_withUnroot() "
963 "on test suite\n")
964 return;
965 }
966 if (PropertiesHelper::IsUserBuild()) {
967 ALOGI("Skipping RunCommandAsRootNonUserBuild_withUnroot on user builds\n");
968 return;
969 }
970
971 // Same test as above, but with unroot property set, which will override su availability.
972 SetUnroot(true);
973 DropRoot();
974
975 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
976 CommandOptions::WithTimeout(1).AsRoot().Build()));
977
978 // AsRoot is ineffective.
979 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
980 EXPECT_THAT(err, StrEq("drop_root_user(): already running as Shell\nstderr\n"));
981}
982
Yifan Hong48e83a12017-10-03 14:10:07 -0700983TEST_F(DumpstateTest, RunCommandAsRootIfAvailableOnUserBuild) {
984 if (!IsStandalone()) {
985 // TODO: temporarily disabled because it might cause other tests to fail after dropping
986 // to Shell - need to refactor tests to avoid this problem)
987 MYLOGE("Skipping DumpstateTest.RunCommandAsRootIfAvailableOnUserBuild() on test suite\n")
988 return;
989 }
990 if (!PropertiesHelper::IsUserBuild()) {
991 // Emulates user build if necessarily.
992 SetBuildType("user");
993 }
994
995 DropRoot();
996
997 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
998 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
999
1000 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
1001 EXPECT_THAT(err, StrEq("stderr\n"));
1002}
1003
1004TEST_F(DumpstateTest, RunCommandAsRootIfAvailableOnDebugBuild) {
1005 if (!IsStandalone()) {
1006 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1007 // to Shell - need to refactor tests to avoid this problem)
1008 MYLOGE("Skipping DumpstateTest.RunCommandAsRootIfAvailableOnDebugBuild() on test suite\n")
1009 return;
1010 }
1011 if (PropertiesHelper::IsUserBuild()) {
1012 ALOGI("Skipping RunCommandAsRootNonUserBuild on user builds\n");
1013 return;
1014 }
1015
1016 DropRoot();
1017
1018 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
1019 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
1020
1021 EXPECT_THAT(out, StrEq("0\nstdout\n"));
1022 EXPECT_THAT(err, StrEq("stderr\n"));
1023}
1024
Nandana Dutt4b392be2018-11-02 16:17:05 +00001025TEST_F(DumpstateTest, RunCommandAsRootIfAvailableOnDebugBuild_withUnroot) {
1026 if (!IsStandalone()) {
1027 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1028 // to Shell - need to refactor tests to avoid this problem)
1029 MYLOGE(
1030 "Skipping DumpstateTest.RunCommandAsRootIfAvailableOnDebugBuild_withUnroot() "
1031 "on test suite\n")
1032 return;
1033 }
1034 if (PropertiesHelper::IsUserBuild()) {
1035 ALOGI("Skipping RunCommandAsRootIfAvailableOnDebugBuild_withUnroot on user builds\n");
1036 return;
1037 }
1038 // Same test as above, but with unroot property set, which will override su availability.
1039 SetUnroot(true);
1040
1041 DropRoot();
1042
1043 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
1044 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
1045
1046 // It's a userdebug build, so "su root" should be available, but unroot=true overrides it.
1047 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
1048 EXPECT_THAT(err, StrEq("stderr\n"));
1049}
1050
Felipe Lemecef02982016-10-03 17:22:22 -07001051TEST_F(DumpstateTest, DumpFileNotFoundNoTitle) {
1052 EXPECT_EQ(-1, DumpFile("", "/I/cant/believe/I/exist"));
1053 EXPECT_THAT(out,
1054 StrEq("*** Error dumping /I/cant/believe/I/exist: No such file or directory\n"));
1055 EXPECT_THAT(err, IsEmpty());
1056}
1057
1058TEST_F(DumpstateTest, DumpFileNotFoundWithTitle) {
1059 EXPECT_EQ(-1, DumpFile("Y U NO EXIST?", "/I/cant/believe/I/exist"));
1060 EXPECT_THAT(err, IsEmpty());
1061 // We don't know the exact duration, so we check the prefix and suffix
1062 EXPECT_THAT(out, StartsWith("*** Error dumping /I/cant/believe/I/exist (Y U NO EXIST?): No "
1063 "such file or directory\n"));
1064 EXPECT_THAT(out, EndsWith("s was the duration of 'Y U NO EXIST?' ------\n"));
1065}
1066
1067TEST_F(DumpstateTest, DumpFileSingleLine) {
Felipe Leme7447d7c2016-11-03 18:12:22 -07001068 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -07001069 EXPECT_THAT(err, IsEmpty());
1070 EXPECT_THAT(out, StrEq("I AM LINE1\n")); // dumpstate adds missing newline
1071}
1072
1073TEST_F(DumpstateTest, DumpFileSingleLineWithNewLine) {
Felipe Leme7447d7c2016-11-03 18:12:22 -07001074 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line-with-newline.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -07001075 EXPECT_THAT(err, IsEmpty());
1076 EXPECT_THAT(out, StrEq("I AM LINE1\n"));
1077}
1078
1079TEST_F(DumpstateTest, DumpFileMultipleLines) {
Felipe Leme7447d7c2016-11-03 18:12:22 -07001080 EXPECT_EQ(0, DumpFile("", kTestDataPath + "multiple-lines.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -07001081 EXPECT_THAT(err, IsEmpty());
1082 EXPECT_THAT(out, StrEq("I AM LINE1\nI AM LINE2\nI AM LINE3\n"));
1083}
1084
1085TEST_F(DumpstateTest, DumpFileMultipleLinesWithNewLine) {
Felipe Leme7447d7c2016-11-03 18:12:22 -07001086 EXPECT_EQ(0, DumpFile("", kTestDataPath + "multiple-lines-with-newline.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -07001087 EXPECT_THAT(err, IsEmpty());
1088 EXPECT_THAT(out, StrEq("I AM LINE1\nI AM LINE2\nI AM LINE3\n"));
1089}
1090
1091TEST_F(DumpstateTest, DumpFileOnDryRunNoTitle) {
1092 SetDryRun(true);
Felipe Leme7447d7c2016-11-03 18:12:22 -07001093 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -07001094 EXPECT_THAT(err, IsEmpty());
1095 EXPECT_THAT(out, IsEmpty());
1096}
1097
1098TEST_F(DumpstateTest, DumpFileOnDryRun) {
1099 SetDryRun(true);
Felipe Leme7447d7c2016-11-03 18:12:22 -07001100 EXPECT_EQ(0, DumpFile("Might as well dump. Dump!", kTestDataPath + "single-line.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -07001101 EXPECT_THAT(err, IsEmpty());
Felipe Leme46b85da2016-11-21 17:40:45 -08001102 EXPECT_THAT(
1103 out, StartsWith("------ Might as well dump. Dump! (" + kTestDataPath + "single-line.txt:"));
1104 EXPECT_THAT(out, HasSubstr("\n\t(skipped on dry run)\n------"));
Felipe Lemecef02982016-10-03 17:22:22 -07001105 EXPECT_THAT(out, EndsWith("s was the duration of 'Might as well dump. Dump!' ------\n"));
Felipe Lemecef02982016-10-03 17:22:22 -07001106}
1107
Felipe Leme75876a22016-10-27 16:31:27 -07001108TEST_F(DumpstateTest, DumpFileUpdateProgress) {
1109 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
1110 ds.listener_ = listener;
1111 ds.listener_name_ = "FoxMulder";
Felipe Leme7447d7c2016-11-03 18:12:22 -07001112 SetProgress(0, 30);
Felipe Leme75876a22016-10-27 16:31:27 -07001113
1114 EXPECT_CALL(*listener, onProgressUpdated(5));
Nandana Duttbabf6c72019-01-15 14:11:12 +00001115 EXPECT_CALL(*listener, onProgress(16)); // 5/30 %
Felipe Leme7447d7c2016-11-03 18:12:22 -07001116 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
Felipe Leme75876a22016-10-27 16:31:27 -07001117
1118 std::string progress_message =
1119 GetProgressMessage(ds.listener_name_, 5, 30); // TODO: unhardcode WEIGHT_FILE (5)?
1120 EXPECT_THAT(err, StrEq(progress_message));
1121 EXPECT_THAT(out, StrEq("I AM LINE1\n")); // dumpstate adds missing newline
1122
1123 ds.listener_.clear();
1124}
1125
Felipe Leme7447d7c2016-11-03 18:12:22 -07001126class DumpstateServiceTest : public DumpstateBaseTest {
Felipe Leme75876a22016-10-27 16:31:27 -07001127 public:
1128 DumpstateService dss;
1129};
1130
1131TEST_F(DumpstateServiceTest, SetListenerNoName) {
1132 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
Felipe Leme009ecbb2016-11-07 10:18:44 -08001133 sp<IDumpstateToken> token;
Vishnu Nair20cf5032018-01-05 13:15:49 -08001134 EXPECT_TRUE(dss.setListener("", listener, /* getSectionDetails = */ false, &token).isOk());
Felipe Leme009ecbb2016-11-07 10:18:44 -08001135 ASSERT_THAT(token, IsNull());
Felipe Leme75876a22016-10-27 16:31:27 -07001136}
1137
1138TEST_F(DumpstateServiceTest, SetListenerNoPointer) {
Felipe Leme009ecbb2016-11-07 10:18:44 -08001139 sp<IDumpstateToken> token;
Vishnu Nair20cf5032018-01-05 13:15:49 -08001140 EXPECT_TRUE(
1141 dss.setListener("whatever", nullptr, /* getSectionDetails = */ false, &token).isOk());
Felipe Leme009ecbb2016-11-07 10:18:44 -08001142 ASSERT_THAT(token, IsNull());
Felipe Leme75876a22016-10-27 16:31:27 -07001143}
1144
1145TEST_F(DumpstateServiceTest, SetListenerTwice) {
1146 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
Felipe Leme009ecbb2016-11-07 10:18:44 -08001147 sp<IDumpstateToken> token;
Vishnu Nair20cf5032018-01-05 13:15:49 -08001148 EXPECT_TRUE(
1149 dss.setListener("whatever", listener, /* getSectionDetails = */ false, &token).isOk());
Felipe Leme009ecbb2016-11-07 10:18:44 -08001150 ASSERT_THAT(token, NotNull());
Felipe Leme75876a22016-10-27 16:31:27 -07001151 EXPECT_THAT(Dumpstate::GetInstance().listener_name_, StrEq("whatever"));
Vishnu Nair20cf5032018-01-05 13:15:49 -08001152 EXPECT_FALSE(Dumpstate::GetInstance().report_section_);
Felipe Leme75876a22016-10-27 16:31:27 -07001153
Felipe Leme009ecbb2016-11-07 10:18:44 -08001154 token.clear();
Vishnu Nair20cf5032018-01-05 13:15:49 -08001155 EXPECT_TRUE(
1156 dss.setListener("whatsoever", listener, /* getSectionDetails = */ false, &token).isOk());
Felipe Leme009ecbb2016-11-07 10:18:44 -08001157 ASSERT_THAT(token, IsNull());
1158 EXPECT_THAT(Dumpstate::GetInstance().listener_name_, StrEq("whatever"));
Vishnu Nair20cf5032018-01-05 13:15:49 -08001159 EXPECT_FALSE(Dumpstate::GetInstance().report_section_);
1160}
1161
1162TEST_F(DumpstateServiceTest, SetListenerWithSectionDetails) {
1163 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
1164 sp<IDumpstateToken> token;
1165 Dumpstate::GetInstance().listener_ = nullptr;
1166 EXPECT_TRUE(
1167 dss.setListener("whatever", listener, /* getSectionDetails = */ true, &token).isOk());
1168 ASSERT_THAT(token, NotNull());
1169 EXPECT_THAT(Dumpstate::GetInstance().listener_name_, StrEq("whatever"));
1170 EXPECT_TRUE(Dumpstate::GetInstance().report_section_);
Felipe Leme75876a22016-10-27 16:31:27 -07001171}
Felipe Leme7447d7c2016-11-03 18:12:22 -07001172
1173class ProgressTest : public DumpstateBaseTest {
1174 public:
1175 Progress GetInstance(int32_t max, double growth_factor, const std::string& path = "") {
1176 return Progress(max, growth_factor, path);
1177 }
1178
1179 void AssertStats(const std::string& path, int32_t expected_runs, int32_t expected_average) {
1180 std::string expected_content =
1181 android::base::StringPrintf("%d %d\n", expected_runs, expected_average);
1182 std::string actual_content;
Felipe Leme46b85da2016-11-21 17:40:45 -08001183 ReadFileToString(path, &actual_content);
Felipe Leme7447d7c2016-11-03 18:12:22 -07001184 ASSERT_THAT(actual_content, StrEq(expected_content)) << "invalid stats on " << path;
1185 }
1186};
1187
1188TEST_F(ProgressTest, SimpleTest) {
1189 Progress progress;
1190 EXPECT_EQ(0, progress.Get());
1191 EXPECT_EQ(Progress::kDefaultMax, progress.GetInitialMax());
1192 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1193
1194 bool max_increased = progress.Inc(1);
1195 EXPECT_EQ(1, progress.Get());
1196 EXPECT_EQ(Progress::kDefaultMax, progress.GetInitialMax());
1197 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1198 EXPECT_FALSE(max_increased);
1199
1200 // Ignore negative increase.
1201 max_increased = progress.Inc(-1);
1202 EXPECT_EQ(1, progress.Get());
1203 EXPECT_EQ(Progress::kDefaultMax, progress.GetInitialMax());
1204 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1205 EXPECT_FALSE(max_increased);
1206}
1207
1208TEST_F(ProgressTest, MaxGrowsInsideNewRange) {
1209 Progress progress = GetInstance(10, 1.2); // 20% growth factor
1210 EXPECT_EQ(0, progress.Get());
1211 EXPECT_EQ(10, progress.GetInitialMax());
1212 EXPECT_EQ(10, progress.GetMax());
1213
1214 // No increase
1215 bool max_increased = progress.Inc(10);
1216 EXPECT_EQ(10, progress.Get());
1217 EXPECT_EQ(10, progress.GetMax());
1218 EXPECT_FALSE(max_increased);
1219
1220 // Increase, with new value < max*20%
1221 max_increased = progress.Inc(1);
1222 EXPECT_EQ(11, progress.Get());
1223 EXPECT_EQ(13, progress.GetMax()); // 11 average * 20% growth = 13.2 = 13
1224 EXPECT_TRUE(max_increased);
1225}
1226
1227TEST_F(ProgressTest, MaxGrowsOutsideNewRange) {
1228 Progress progress = GetInstance(10, 1.2); // 20% growth factor
1229 EXPECT_EQ(0, progress.Get());
1230 EXPECT_EQ(10, progress.GetInitialMax());
1231 EXPECT_EQ(10, progress.GetMax());
1232
1233 // No increase
1234 bool max_increased = progress.Inc(10);
1235 EXPECT_EQ(10, progress.Get());
1236 EXPECT_EQ(10, progress.GetMax());
1237 EXPECT_FALSE(max_increased);
1238
1239 // Increase, with new value > max*20%
1240 max_increased = progress.Inc(5);
1241 EXPECT_EQ(15, progress.Get());
1242 EXPECT_EQ(18, progress.GetMax()); // 15 average * 20% growth = 18
1243 EXPECT_TRUE(max_increased);
1244}
1245
1246TEST_F(ProgressTest, InvalidPath) {
1247 Progress progress("/devil/null");
1248 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1249}
1250
1251TEST_F(ProgressTest, EmptyFile) {
1252 Progress progress(CopyTextFileFixture("empty-file.txt"));
1253 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1254}
1255
1256TEST_F(ProgressTest, InvalidLine1stEntryNAN) {
1257 Progress progress(CopyTextFileFixture("stats-invalid-1st-NAN.txt"));
1258 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1259}
1260
1261TEST_F(ProgressTest, InvalidLine2ndEntryNAN) {
1262 Progress progress(CopyTextFileFixture("stats-invalid-2nd-NAN.txt"));
1263 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1264}
1265
1266TEST_F(ProgressTest, InvalidLineBothNAN) {
1267 Progress progress(CopyTextFileFixture("stats-invalid-both-NAN.txt"));
1268 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1269}
1270
1271TEST_F(ProgressTest, InvalidLine1stEntryNegative) {
1272 Progress progress(CopyTextFileFixture("stats-invalid-1st-negative.txt"));
1273 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1274}
1275
1276TEST_F(ProgressTest, InvalidLine2ndEntryNegative) {
1277 Progress progress(CopyTextFileFixture("stats-invalid-2nd-negative.txt"));
1278 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1279}
1280
1281TEST_F(ProgressTest, InvalidLine1stEntryTooBig) {
1282 Progress progress(CopyTextFileFixture("stats-invalid-1st-too-big.txt"));
1283 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1284}
1285
1286TEST_F(ProgressTest, InvalidLine2ndEntryTooBig) {
1287 Progress progress(CopyTextFileFixture("stats-invalid-2nd-too-big.txt"));
1288 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1289}
1290
1291// Tests stats are properly saved when the file does not exists.
1292TEST_F(ProgressTest, FirstTime) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001293 if (!IsStandalone()) {
1294 // TODO: temporarily disabled because it's failing when running as suite
1295 MYLOGE("Skipping ProgressTest.FirstTime() on test suite\n")
1296 return;
1297 }
1298
Felipe Leme7447d7c2016-11-03 18:12:22 -07001299 std::string path = kTestDataPath + "FirstTime.txt";
1300 android::base::RemoveFileIfExists(path);
1301
1302 Progress run1(path);
1303 EXPECT_EQ(0, run1.Get());
1304 EXPECT_EQ(Progress::kDefaultMax, run1.GetInitialMax());
1305 EXPECT_EQ(Progress::kDefaultMax, run1.GetMax());
1306
1307 bool max_increased = run1.Inc(20);
1308 EXPECT_EQ(20, run1.Get());
1309 EXPECT_EQ(Progress::kDefaultMax, run1.GetMax());
1310 EXPECT_FALSE(max_increased);
1311
1312 run1.Save();
1313 AssertStats(path, 1, 20);
1314}
1315
1316// Tests what happens when the persistent settings contains the average duration of 1 run.
1317// Data on file is 1 run and 109 average.
1318TEST_F(ProgressTest, SecondTime) {
1319 std::string path = CopyTextFileFixture("stats-one-run-no-newline.txt");
1320
1321 Progress run1 = GetInstance(-42, 1.2, path);
1322 EXPECT_EQ(0, run1.Get());
1323 EXPECT_EQ(10, run1.GetInitialMax());
1324 EXPECT_EQ(10, run1.GetMax());
1325
1326 bool max_increased = run1.Inc(20);
1327 EXPECT_EQ(20, run1.Get());
1328 EXPECT_EQ(24, run1.GetMax());
1329 EXPECT_TRUE(max_increased);
1330
1331 // Average now is 2 runs and (10 + 20)/ 2 = 15
1332 run1.Save();
1333 AssertStats(path, 2, 15);
1334
1335 Progress run2 = GetInstance(-42, 1.2, path);
1336 EXPECT_EQ(0, run2.Get());
1337 EXPECT_EQ(15, run2.GetInitialMax());
1338 EXPECT_EQ(15, run2.GetMax());
1339
1340 max_increased = run2.Inc(25);
1341 EXPECT_EQ(25, run2.Get());
1342 EXPECT_EQ(30, run2.GetMax());
1343 EXPECT_TRUE(max_increased);
1344
1345 // Average now is 3 runs and (15 * 2 + 25)/ 3 = 18.33 = 18
1346 run2.Save();
1347 AssertStats(path, 3, 18);
1348
1349 Progress run3 = GetInstance(-42, 1.2, path);
1350 EXPECT_EQ(0, run3.Get());
1351 EXPECT_EQ(18, run3.GetInitialMax());
1352 EXPECT_EQ(18, run3.GetMax());
1353
1354 // Make sure average decreases as well
1355 max_increased = run3.Inc(5);
1356 EXPECT_EQ(5, run3.Get());
1357 EXPECT_EQ(18, run3.GetMax());
1358 EXPECT_FALSE(max_increased);
1359
1360 // Average now is 4 runs and (18 * 3 + 5)/ 4 = 14.75 = 14
1361 run3.Save();
1362 AssertStats(path, 4, 14);
1363}
1364
1365// Tests what happens when the persistent settings contains the average duration of 2 runs.
1366// Data on file is 2 runs and 15 average.
1367TEST_F(ProgressTest, ThirdTime) {
1368 std::string path = CopyTextFileFixture("stats-two-runs.txt");
1369 AssertStats(path, 2, 15); // Sanity check
1370
1371 Progress run1 = GetInstance(-42, 1.2, path);
1372 EXPECT_EQ(0, run1.Get());
1373 EXPECT_EQ(15, run1.GetInitialMax());
1374 EXPECT_EQ(15, run1.GetMax());
1375
1376 bool max_increased = run1.Inc(20);
1377 EXPECT_EQ(20, run1.Get());
1378 EXPECT_EQ(24, run1.GetMax());
1379 EXPECT_TRUE(max_increased);
1380
1381 // Average now is 3 runs and (15 * 2 + 20)/ 3 = 16.66 = 16
1382 run1.Save();
1383 AssertStats(path, 3, 16);
1384}
1385
Felipe Leme46b85da2016-11-21 17:40:45 -08001386class DumpstateUtilTest : public DumpstateBaseTest {
1387 public:
1388 void SetUp() {
1389 DumpstateBaseTest::SetUp();
1390 SetDryRun(false);
1391 }
1392
Felipe Leme46b85da2016-11-21 17:40:45 -08001393 void CaptureFdOut() {
Felipe Lemef0292972016-11-22 13:57:05 -08001394 ReadFileToString(path_, &out);
Felipe Leme46b85da2016-11-21 17:40:45 -08001395 }
1396
1397 void CreateFd(const std::string& name) {
1398 path_ = kTestDataPath + name;
1399 MYLOGD("Creating fd for file %s\n", path_.c_str());
1400
1401 fd = TEMP_FAILURE_RETRY(open(path_.c_str(),
1402 O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW,
1403 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH));
1404 ASSERT_GE(fd, 0) << "could not create FD for path " << path_;
1405 }
1406
1407 // Runs a command into the `fd` and capture `stderr`.
Felipe Lemef0292972016-11-22 13:57:05 -08001408 int RunCommand(const std::string& title, const std::vector<std::string>& full_command,
Felipe Leme46b85da2016-11-21 17:40:45 -08001409 const CommandOptions& options = CommandOptions::DEFAULT) {
1410 CaptureStderr();
Felipe Lemef0292972016-11-22 13:57:05 -08001411 int status = RunCommandToFd(fd, title, full_command, options);
Felipe Leme46b85da2016-11-21 17:40:45 -08001412 close(fd);
1413
1414 CaptureFdOut();
1415 err = GetCapturedStderr();
1416 return status;
1417 }
1418
1419 // Dumps a file and into the `fd` and `stderr`.
Felipe Lemef0292972016-11-22 13:57:05 -08001420 int DumpFile(const std::string& title, const std::string& path) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001421 CaptureStderr();
Felipe Lemef0292972016-11-22 13:57:05 -08001422 int status = DumpFileToFd(fd, title, path);
Felipe Leme46b85da2016-11-21 17:40:45 -08001423 close(fd);
1424
1425 CaptureFdOut();
1426 err = GetCapturedStderr();
1427 return status;
1428 }
1429
Ecco Park61ffcf72016-10-27 15:46:26 -07001430 // Find out the pid of the process_name
1431 int FindPidOfProcess(const std::string& process_name) {
1432 CaptureStderr();
1433 int status = GetPidByName(process_name);
1434 err = GetCapturedStderr();
1435 return status;
1436 }
1437
Felipe Leme46b85da2016-11-21 17:40:45 -08001438 int fd;
1439
1440 // 'fd` output and `stderr` from the last command ran.
1441 std::string out, err;
1442
1443 private:
1444 std::string path_;
1445};
1446
1447TEST_F(DumpstateUtilTest, RunCommandNoArgs) {
Felipe Lemef0292972016-11-22 13:57:05 -08001448 CreateFd("RunCommandNoArgs.txt");
1449 EXPECT_EQ(-1, RunCommand("", {}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001450}
1451
Felipe Lemef0292972016-11-22 13:57:05 -08001452TEST_F(DumpstateUtilTest, RunCommandNoTitle) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001453 CreateFd("RunCommandWithNoArgs.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001454 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001455 EXPECT_THAT(out, StrEq("stdout\n"));
1456 EXPECT_THAT(err, StrEq("stderr\n"));
1457}
1458
Felipe Lemef0292972016-11-22 13:57:05 -08001459TEST_F(DumpstateUtilTest, RunCommandWithTitle) {
1460 CreateFd("RunCommandWithNoArgs.txt");
1461 EXPECT_EQ(0, RunCommand("I AM GROOT", {kSimpleCommand}));
1462 EXPECT_THAT(out, StrEq("------ I AM GROOT (" + kSimpleCommand + ") ------\nstdout\n"));
1463 EXPECT_THAT(err, StrEq("stderr\n"));
1464}
1465
Felipe Leme46b85da2016-11-21 17:40:45 -08001466TEST_F(DumpstateUtilTest, RunCommandWithOneArg) {
1467 CreateFd("RunCommandWithOneArg.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001468 EXPECT_EQ(0, RunCommand("", {kEchoCommand, "one"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001469 EXPECT_THAT(err, IsEmpty());
1470 EXPECT_THAT(out, StrEq("one\n"));
1471}
1472
1473TEST_F(DumpstateUtilTest, RunCommandWithMultipleArgs) {
1474 CreateFd("RunCommandWithMultipleArgs.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001475 EXPECT_EQ(0, RunCommand("", {kEchoCommand, "one", "is", "the", "loniest", "number"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001476 EXPECT_THAT(err, IsEmpty());
1477 EXPECT_THAT(out, StrEq("one is the loniest number\n"));
1478}
1479
1480TEST_F(DumpstateUtilTest, RunCommandWithLoggingMessage) {
1481 CreateFd("RunCommandWithLoggingMessage.txt");
1482 EXPECT_EQ(
Felipe Lemef0292972016-11-22 13:57:05 -08001483 0, RunCommand("", {kSimpleCommand},
Felipe Leme46b85da2016-11-21 17:40:45 -08001484 CommandOptions::WithTimeout(10).Log("COMMAND, Y U NO LOG FIRST?").Build()));
1485 EXPECT_THAT(out, StrEq("stdout\n"));
1486 EXPECT_THAT(err, StrEq("COMMAND, Y U NO LOG FIRST?stderr\n"));
1487}
1488
1489TEST_F(DumpstateUtilTest, RunCommandRedirectStderr) {
1490 CreateFd("RunCommandRedirectStderr.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001491 EXPECT_EQ(0, RunCommand("", {kSimpleCommand},
1492 CommandOptions::WithTimeout(10).RedirectStderr().Build()));
Felipe Leme46b85da2016-11-21 17:40:45 -08001493 EXPECT_THAT(out, IsEmpty());
1494 EXPECT_THAT(err, StrEq("stdout\nstderr\n"));
1495}
1496
1497TEST_F(DumpstateUtilTest, RunCommandDryRun) {
1498 CreateFd("RunCommandDryRun.txt");
1499 SetDryRun(true);
Felipe Lemef0292972016-11-22 13:57:05 -08001500 EXPECT_EQ(0, RunCommand("I AM GROOT", {kSimpleCommand}));
1501 EXPECT_THAT(out, StrEq(android::base::StringPrintf(
1502 "------ I AM GROOT (%s) ------\n\t(skipped on dry run)\n",
1503 kSimpleCommand.c_str())));
1504 EXPECT_THAT(err, IsEmpty());
1505}
1506
1507TEST_F(DumpstateUtilTest, RunCommandDryRunNoTitle) {
1508 CreateFd("RunCommandDryRun.txt");
1509 SetDryRun(true);
1510 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001511 EXPECT_THAT(
1512 out, StrEq(android::base::StringPrintf("%s: skipped on dry run\n", kSimpleCommand.c_str())));
1513 EXPECT_THAT(err, IsEmpty());
1514}
1515
1516TEST_F(DumpstateUtilTest, RunCommandDryRunAlways) {
1517 CreateFd("RunCommandDryRunAlways.txt");
1518 SetDryRun(true);
Felipe Lemef0292972016-11-22 13:57:05 -08001519 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(10).Always().Build()));
Felipe Leme46b85da2016-11-21 17:40:45 -08001520 EXPECT_THAT(out, StrEq("stdout\n"));
1521 EXPECT_THAT(err, StrEq("stderr\n"));
1522}
1523
1524TEST_F(DumpstateUtilTest, RunCommandNotFound) {
1525 CreateFd("RunCommandNotFound.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001526 EXPECT_NE(0, RunCommand("", {"/there/cannot/be/such/command"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001527 EXPECT_THAT(out, StartsWith("*** command '/there/cannot/be/such/command' failed: exit code"));
1528 EXPECT_THAT(err, StartsWith("execvp on command '/there/cannot/be/such/command' failed"));
1529}
1530
1531TEST_F(DumpstateUtilTest, RunCommandFails) {
1532 CreateFd("RunCommandFails.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001533 EXPECT_EQ(42, RunCommand("", {kSimpleCommand, "--exit", "42"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001534 EXPECT_THAT(out, StrEq("stdout\n*** command '" + kSimpleCommand +
1535 " --exit 42' failed: exit code 42\n"));
1536 EXPECT_THAT(err, StrEq("stderr\n*** command '" + kSimpleCommand +
1537 " --exit 42' failed: exit code 42\n"));
1538}
1539
1540TEST_F(DumpstateUtilTest, RunCommandCrashes) {
1541 CreateFd("RunCommandCrashes.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001542 EXPECT_NE(0, RunCommand("", {kSimpleCommand, "--crash"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001543 // We don't know the exit code, so check just the prefix.
1544 EXPECT_THAT(
1545 out, StartsWith("stdout\n*** command '" + kSimpleCommand + " --crash' failed: exit code"));
1546 EXPECT_THAT(
1547 err, StartsWith("stderr\n*** command '" + kSimpleCommand + " --crash' failed: exit code"));
1548}
1549
Vishnu Nair6921f802017-11-22 09:17:23 -08001550TEST_F(DumpstateUtilTest, RunCommandTimesoutWithSec) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001551 CreateFd("RunCommandTimesout.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001552 EXPECT_EQ(-1, RunCommand("", {kSimpleCommand, "--sleep", "2"},
1553 CommandOptions::WithTimeout(1).Build()));
Felipe Leme46b85da2016-11-21 17:40:45 -08001554 EXPECT_THAT(out, StartsWith("stdout line1\n*** command '" + kSimpleCommand +
1555 " --sleep 2' timed out after 1"));
1556 EXPECT_THAT(err, StartsWith("sleeping for 2s\n*** command '" + kSimpleCommand +
1557 " --sleep 2' timed out after 1"));
1558}
1559
Vishnu Nair6921f802017-11-22 09:17:23 -08001560TEST_F(DumpstateUtilTest, RunCommandTimesoutWithMsec) {
1561 CreateFd("RunCommandTimesout.txt");
1562 EXPECT_EQ(-1, RunCommand("", {kSimpleCommand, "--sleep", "2"},
1563 CommandOptions::WithTimeoutInMs(1000).Build()));
1564 EXPECT_THAT(out, StartsWith("stdout line1\n*** command '" + kSimpleCommand +
1565 " --sleep 2' timed out after 1"));
1566 EXPECT_THAT(err, StartsWith("sleeping for 2s\n*** command '" + kSimpleCommand +
1567 " --sleep 2' timed out after 1"));
1568}
1569
1570
Felipe Leme46b85da2016-11-21 17:40:45 -08001571TEST_F(DumpstateUtilTest, RunCommandIsKilled) {
1572 CreateFd("RunCommandIsKilled.txt");
1573 CaptureStderr();
1574
1575 std::thread t([=]() {
Felipe Lemef0292972016-11-22 13:57:05 -08001576 EXPECT_EQ(SIGTERM, RunCommandToFd(fd, "", {kSimpleCommand, "--pid", "--sleep", "20"},
Felipe Leme46b85da2016-11-21 17:40:45 -08001577 CommandOptions::WithTimeout(100).Always().Build()));
1578 });
1579
1580 // Capture pid and pre-sleep output.
1581 sleep(1); // Wait a little bit to make sure pid and 1st line were printed.
1582 std::string err = GetCapturedStderr();
1583 EXPECT_THAT(err, StrEq("sleeping for 20s\n"));
1584
1585 CaptureFdOut();
1586 std::vector<std::string> lines = android::base::Split(out, "\n");
1587 ASSERT_EQ(3, (int)lines.size()) << "Invalid lines before sleep: " << out;
1588
1589 int pid = atoi(lines[0].c_str());
1590 EXPECT_THAT(lines[1], StrEq("stdout line1"));
1591 EXPECT_THAT(lines[2], IsEmpty()); // \n
1592
1593 // Then kill the process.
1594 CaptureFdOut();
1595 CaptureStderr();
1596 ASSERT_EQ(0, kill(pid, SIGTERM)) << "failed to kill pid " << pid;
1597 t.join();
1598
1599 // Finally, check output after murder.
1600 CaptureFdOut();
1601 err = GetCapturedStderr();
1602
1603 // out starts with the pid, which is an unknown
1604 EXPECT_THAT(out, EndsWith("stdout line1\n*** command '" + kSimpleCommand +
1605 " --pid --sleep 20' failed: killed by signal 15\n"));
1606 EXPECT_THAT(err, StrEq("*** command '" + kSimpleCommand +
1607 " --pid --sleep 20' failed: killed by signal 15\n"));
1608}
1609
1610TEST_F(DumpstateUtilTest, RunCommandAsRootUserBuild) {
1611 if (!IsStandalone()) {
1612 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1613 // to Shell - need to refactor tests to avoid this problem)
1614 MYLOGE("Skipping DumpstateUtilTest.RunCommandAsRootUserBuild() on test suite\n")
1615 return;
1616 }
1617 CreateFd("RunCommandAsRootUserBuild.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001618 if (!PropertiesHelper::IsUserBuild()) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001619 // Emulates user build if necessarily.
1620 SetBuildType("user");
1621 }
1622
1623 DropRoot();
1624
Felipe Lemef0292972016-11-22 13:57:05 -08001625 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).AsRoot().Build()));
Felipe Leme46b85da2016-11-21 17:40:45 -08001626
1627 // We don't know the exact path of su, so we just check for the 'root ...' commands
1628 EXPECT_THAT(out, StartsWith("Skipping"));
1629 EXPECT_THAT(out, EndsWith("root " + kSimpleCommand + "' on user build.\n"));
1630 EXPECT_THAT(err, IsEmpty());
1631}
1632
1633TEST_F(DumpstateUtilTest, RunCommandAsRootNonUserBuild) {
1634 if (!IsStandalone()) {
1635 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1636 // to Shell - need to refactor tests to avoid this problem)
1637 MYLOGE("Skipping DumpstateUtilTest.RunCommandAsRootNonUserBuild() on test suite\n")
1638 return;
1639 }
1640 CreateFd("RunCommandAsRootNonUserBuild.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001641 if (PropertiesHelper::IsUserBuild()) {
Felipe Leme7447d7c2016-11-03 18:12:22 -07001642 ALOGI("Skipping RunCommandAsRootNonUserBuild on user builds\n");
1643 return;
1644 }
1645
1646 DropRoot();
1647
Felipe Lemef0292972016-11-22 13:57:05 -08001648 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
1649 CommandOptions::WithTimeout(1).AsRoot().Build()));
Felipe Leme7447d7c2016-11-03 18:12:22 -07001650
1651 EXPECT_THAT(out, StrEq("0\nstdout\n"));
1652 EXPECT_THAT(err, StrEq("stderr\n"));
1653}
Felipe Leme46b85da2016-11-21 17:40:45 -08001654
Yifan Hong48e83a12017-10-03 14:10:07 -07001655
1656TEST_F(DumpstateUtilTest, RunCommandAsRootIfAvailableOnUserBuild) {
1657 if (!IsStandalone()) {
1658 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1659 // to Shell - need to refactor tests to avoid this problem)
1660 MYLOGE("Skipping DumpstateUtilTest.RunCommandAsRootIfAvailableOnUserBuild() on test suite\n")
1661 return;
1662 }
1663 CreateFd("RunCommandAsRootIfAvailableOnUserBuild.txt");
1664 if (!PropertiesHelper::IsUserBuild()) {
1665 // Emulates user build if necessarily.
1666 SetBuildType("user");
1667 }
1668
1669 DropRoot();
1670
1671 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
1672 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
1673
1674 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
1675 EXPECT_THAT(err, StrEq("stderr\n"));
1676}
1677
1678TEST_F(DumpstateUtilTest, RunCommandAsRootIfAvailableOnDebugBuild) {
1679 if (!IsStandalone()) {
1680 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1681 // to Shell - need to refactor tests to avoid this problem)
1682 MYLOGE("Skipping DumpstateUtilTest.RunCommandAsRootIfAvailableOnDebugBuild() on test suite\n")
1683 return;
1684 }
1685 CreateFd("RunCommandAsRootIfAvailableOnDebugBuild.txt");
1686 if (PropertiesHelper::IsUserBuild()) {
1687 ALOGI("Skipping RunCommandAsRootNonUserBuild on user builds\n");
1688 return;
1689 }
1690
1691 DropRoot();
1692
1693 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
1694 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
1695
1696 EXPECT_THAT(out, StrEq("0\nstdout\n"));
1697 EXPECT_THAT(err, StrEq("stderr\n"));
1698}
1699
Felipe Leme46b85da2016-11-21 17:40:45 -08001700TEST_F(DumpstateUtilTest, RunCommandDropRoot) {
1701 if (!IsStandalone()) {
1702 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1703 // to Shell - need to refactor tests to avoid this problem)
1704 MYLOGE("Skipping DumpstateUtilTest.RunCommandDropRoot() on test suite\n")
1705 return;
1706 }
1707 CreateFd("RunCommandDropRoot.txt");
1708 // First check root case - only available when running with 'adb root'.
1709 uid_t uid = getuid();
1710 if (uid == 0) {
Felipe Lemef0292972016-11-22 13:57:05 -08001711 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001712 EXPECT_THAT(out, StrEq("0\nstdout\n"));
1713 EXPECT_THAT(err, StrEq("stderr\n"));
1714 return;
1715 }
1716 // Then run dropping root.
Felipe Lemef0292972016-11-22 13:57:05 -08001717 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
Felipe Leme46b85da2016-11-21 17:40:45 -08001718 CommandOptions::WithTimeout(1).DropRoot().Build()));
1719 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
1720 EXPECT_THAT(err, StrEq("drop_root_user(): already running as Shell\nstderr\n"));
1721}
1722
Felipe Lemef0292972016-11-22 13:57:05 -08001723TEST_F(DumpstateUtilTest, DumpFileNotFoundNoTitle) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001724 CreateFd("DumpFileNotFound.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001725 EXPECT_EQ(-1, DumpFile("", "/I/cant/believe/I/exist"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001726 EXPECT_THAT(out,
1727 StrEq("*** Error dumping /I/cant/believe/I/exist: No such file or directory\n"));
1728 EXPECT_THAT(err, IsEmpty());
1729}
1730
Felipe Lemef0292972016-11-22 13:57:05 -08001731TEST_F(DumpstateUtilTest, DumpFileNotFoundWithTitle) {
1732 CreateFd("DumpFileNotFound.txt");
1733 EXPECT_EQ(-1, DumpFile("Y U NO EXIST?", "/I/cant/believe/I/exist"));
1734 EXPECT_THAT(out, StrEq("*** Error dumping /I/cant/believe/I/exist (Y U NO EXIST?): No such "
1735 "file or directory\n"));
1736 EXPECT_THAT(err, IsEmpty());
1737}
1738
Felipe Leme46b85da2016-11-21 17:40:45 -08001739TEST_F(DumpstateUtilTest, DumpFileSingleLine) {
1740 CreateFd("DumpFileSingleLine.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001741 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001742 EXPECT_THAT(err, IsEmpty());
1743 EXPECT_THAT(out, StrEq("I AM LINE1\n")); // dumpstate adds missing newline
1744}
1745
1746TEST_F(DumpstateUtilTest, DumpFileSingleLineWithNewLine) {
1747 CreateFd("DumpFileSingleLineWithNewLine.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001748 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line-with-newline.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001749 EXPECT_THAT(err, IsEmpty());
1750 EXPECT_THAT(out, StrEq("I AM LINE1\n"));
1751}
1752
1753TEST_F(DumpstateUtilTest, DumpFileMultipleLines) {
1754 CreateFd("DumpFileMultipleLines.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001755 EXPECT_EQ(0, DumpFile("", kTestDataPath + "multiple-lines.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001756 EXPECT_THAT(err, IsEmpty());
1757 EXPECT_THAT(out, StrEq("I AM LINE1\nI AM LINE2\nI AM LINE3\n"));
1758}
1759
1760TEST_F(DumpstateUtilTest, DumpFileMultipleLinesWithNewLine) {
1761 CreateFd("DumpFileMultipleLinesWithNewLine.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001762 EXPECT_EQ(0, DumpFile("", kTestDataPath + "multiple-lines-with-newline.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001763 EXPECT_THAT(err, IsEmpty());
1764 EXPECT_THAT(out, StrEq("I AM LINE1\nI AM LINE2\nI AM LINE3\n"));
1765}
1766
Felipe Lemef0292972016-11-22 13:57:05 -08001767TEST_F(DumpstateUtilTest, DumpFileOnDryRunNoTitle) {
1768 CreateFd("DumpFileOnDryRun.txt");
1769 SetDryRun(true);
1770 std::string path = kTestDataPath + "single-line.txt";
1771 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
1772 EXPECT_THAT(err, IsEmpty());
1773 EXPECT_THAT(out, StrEq(path + ": skipped on dry run\n"));
1774}
1775
Felipe Leme46b85da2016-11-21 17:40:45 -08001776TEST_F(DumpstateUtilTest, DumpFileOnDryRun) {
1777 CreateFd("DumpFileOnDryRun.txt");
1778 SetDryRun(true);
1779 std::string path = kTestDataPath + "single-line.txt";
Felipe Lemef0292972016-11-22 13:57:05 -08001780 EXPECT_EQ(0, DumpFile("Might as well dump. Dump!", kTestDataPath + "single-line.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001781 EXPECT_THAT(err, IsEmpty());
Felipe Lemef0292972016-11-22 13:57:05 -08001782 EXPECT_THAT(
1783 out, StartsWith("------ Might as well dump. Dump! (" + kTestDataPath + "single-line.txt:"));
1784 EXPECT_THAT(out, EndsWith("skipped on dry run\n"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001785}
Ecco Park61ffcf72016-10-27 15:46:26 -07001786
1787TEST_F(DumpstateUtilTest, FindingPidWithExistingProcess) {
1788 // init process always has pid 1.
1789 EXPECT_EQ(1, FindPidOfProcess("init"));
1790 EXPECT_THAT(err, IsEmpty());
1791}
1792
1793TEST_F(DumpstateUtilTest, FindingPidWithNotExistingProcess) {
1794 // find the process with abnormal name.
1795 EXPECT_EQ(-1, FindPidOfProcess("abcdef12345-543"));
1796 EXPECT_THAT(err, StrEq("can't find the pid\n"));
1797}
Felipe Leme47e9be22016-12-21 15:37:07 -08001798
1799} // namespace dumpstate
1800} // namespace os
1801} // namespace android