blob: fcf9371a4f99dbbd3c2958b34d0283196cd89084 [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:
62 MOCK_METHOD1(onProgressUpdated, binder::Status(int32_t progress));
63 MOCK_METHOD1(onMaxProgressUpdated, binder::Status(int32_t max_progress));
Vishnu Nair20cf5032018-01-05 13:15:49 -080064 MOCK_METHOD4(onSectionComplete, binder::Status(const ::std::string& name, int32_t status,
65 int32_t size, int32_t durationMs));
Felipe Leme75876a22016-10-27 16:31:27 -070066
67 protected:
68 MOCK_METHOD0(onAsBinder, IBinder*());
69};
70
Felipe Leme46b85da2016-11-21 17:40:45 -080071static int calls_;
72
Felipe Leme7447d7c2016-11-03 18:12:22 -070073// Base class for all tests in this file
74class DumpstateBaseTest : public Test {
Felipe Leme46b85da2016-11-21 17:40:45 -080075 public:
76 virtual void SetUp() override {
77 calls_++;
Felipe Lemef0292972016-11-22 13:57:05 -080078 SetDryRun(false);
Felipe Leme46b85da2016-11-21 17:40:45 -080079 }
80
Felipe Lemef0292972016-11-22 13:57:05 -080081 void SetDryRun(bool dry_run) const {
82 PropertiesHelper::dry_run_ = dry_run;
83 }
84
85 void SetBuildType(const std::string& build_type) const {
86 PropertiesHelper::build_type_ = build_type;
87 }
88
Nandana Dutt4b392be2018-11-02 16:17:05 +000089 void SetUnroot(bool unroot) const {
90 PropertiesHelper::unroot_ = unroot;
91 }
92
Felipe Lemef0292972016-11-22 13:57:05 -080093 bool IsStandalone() const {
Felipe Leme46b85da2016-11-21 17:40:45 -080094 return calls_ == 1;
95 }
96
Felipe Lemef0292972016-11-22 13:57:05 -080097 void DropRoot() const {
98 DropRootUser();
Felipe Leme46b85da2016-11-21 17:40:45 -080099 uid_t uid = getuid();
100 ASSERT_EQ(2000, (int)uid);
101 }
102
Felipe Leme7447d7c2016-11-03 18:12:22 -0700103 protected:
104 const std::string kTestPath = dirname(android::base::GetExecutablePath().c_str());
105 const std::string kFixturesPath = kTestPath + "/../dumpstate_test_fixture/";
Felipe Leme7fb8dee2017-08-25 10:15:01 -0700106 const std::string kTestDataPath = kFixturesPath + "tests/testdata/";
Felipe Leme7447d7c2016-11-03 18:12:22 -0700107 const std::string kSimpleCommand = kFixturesPath + "dumpstate_test_fixture";
108 const std::string kEchoCommand = "/system/bin/echo";
109
110 /*
111 * Copies a text file fixture to a temporary file, returning it's path.
112 *
113 * Useful in cases where the test case changes the content of the tile.
114 */
115 std::string CopyTextFileFixture(const std::string& relative_name) {
116 std::string from = kTestDataPath + relative_name;
117 // Not using TemporaryFile because it's deleted at the end, and it's useful to keep it
118 // around for poking when the test fails.
119 std::string to = kTestDataPath + relative_name + ".tmp";
120 ALOGD("CopyTextFileFixture: from %s to %s\n", from.c_str(), to.c_str());
121 android::base::RemoveFileIfExists(to);
122 CopyTextFile(from, to);
123 return to.c_str();
124 }
125
Felipe Leme46b85da2016-11-21 17:40:45 -0800126 // Need functions that returns void to use assertions -
Felipe Leme7447d7c2016-11-03 18:12:22 -0700127 // https://github.com/google/googletest/blob/master/googletest/docs/AdvancedGuide.md#assertion-placement
Felipe Leme46b85da2016-11-21 17:40:45 -0800128 void ReadFileToString(const std::string& path, std::string* content) {
129 ASSERT_TRUE(android::base::ReadFileToString(path, content))
130 << "could not read contents from " << path;
131 }
132 void WriteStringToFile(const std::string& content, const std::string& path) {
133 ASSERT_TRUE(android::base::WriteStringToFile(content, path))
134 << "could not write contents to " << path;
135 }
136
137 private:
Felipe Leme7447d7c2016-11-03 18:12:22 -0700138 void CopyTextFile(const std::string& from, const std::string& to) {
139 std::string content;
Felipe Leme46b85da2016-11-21 17:40:45 -0800140 ReadFileToString(from, &content);
141 WriteStringToFile(content, to);
Felipe Leme7447d7c2016-11-03 18:12:22 -0700142 }
143};
144
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100145class DumpOptionsTest : public Test {
146 public:
147 virtual ~DumpOptionsTest() {
148 }
149 virtual void SetUp() {
150 options_ = Dumpstate::DumpOptions();
151 }
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000152 void TearDown() {
153 // Reset the property
154 property_set("dumpstate.options", "");
155 }
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100156 Dumpstate::DumpOptions options_;
157};
158
159TEST_F(DumpOptionsTest, InitializeNone) {
160 // clang-format off
161 char* argv[] = {
162 const_cast<char*>("dumpstate")
163 };
164 // clang-format on
165
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100166 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
167
168 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
Nandana Dutt58d72e22018-11-16 10:30:48 +0000169
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100170 EXPECT_FALSE(options_.do_add_date);
171 EXPECT_FALSE(options_.do_zip_file);
172 EXPECT_EQ("", options_.use_outfile);
173 EXPECT_FALSE(options_.use_socket);
174 EXPECT_FALSE(options_.use_control_socket);
175 EXPECT_FALSE(options_.show_header_only);
176 EXPECT_TRUE(options_.do_vibrate);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000177 EXPECT_FALSE(options_.do_fb);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100178 EXPECT_FALSE(options_.do_progress_updates);
179 EXPECT_FALSE(options_.is_remote_mode);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000180 EXPECT_FALSE(options_.do_broadcast);
181}
182
183TEST_F(DumpOptionsTest, InitializeAdbBugreport) {
184 // clang-format off
185 char* argv[] = {
186 const_cast<char*>("dumpstatez"),
187 const_cast<char*>("-S"),
188 const_cast<char*>("-d"),
189 const_cast<char*>("-z"),
190 const_cast<char*>("-o abc"),
191 };
192 // clang-format on
193
194 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
195
196 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
197 EXPECT_TRUE(options_.do_add_date);
198 EXPECT_TRUE(options_.do_zip_file);
199 EXPECT_TRUE(options_.use_control_socket);
200 EXPECT_EQ(" abc", std::string(options_.use_outfile));
201
202 // Other options retain default values
203 EXPECT_TRUE(options_.do_vibrate);
204 EXPECT_FALSE(options_.show_header_only);
205 EXPECT_FALSE(options_.do_fb);
206 EXPECT_FALSE(options_.do_progress_updates);
207 EXPECT_FALSE(options_.is_remote_mode);
208 EXPECT_FALSE(options_.do_broadcast);
209 EXPECT_FALSE(options_.use_socket);
210}
211
212TEST_F(DumpOptionsTest, InitializeAdbShellBugreport) {
213 // clang-format off
214 char* argv[] = {
215 const_cast<char*>("dumpstate"),
216 const_cast<char*>("-s"),
217 };
218 // clang-format on
219
220 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
221
222 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
223 EXPECT_TRUE(options_.use_socket);
224
225 // Other options retain default values
226 EXPECT_TRUE(options_.do_vibrate);
227 EXPECT_EQ("", options_.use_outfile);
228 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"),
246 const_cast<char*>("-o abc"),
247 };
248 // clang-format on
249 property_set("dumpstate.options", "bugreportfull");
250
251 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
252
253 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
254 EXPECT_TRUE(options_.do_add_date);
255 EXPECT_TRUE(options_.do_fb);
256 EXPECT_TRUE(options_.do_zip_file);
Nandana Dutt58d72e22018-11-16 10:30:48 +0000257 EXPECT_TRUE(options_.do_broadcast);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000258 EXPECT_EQ(" abc", std::string(options_.use_outfile));
259
260 // Other options retain default values
261 EXPECT_TRUE(options_.do_vibrate);
262 EXPECT_FALSE(options_.use_control_socket);
263 EXPECT_FALSE(options_.show_header_only);
264 EXPECT_FALSE(options_.do_progress_updates);
265 EXPECT_FALSE(options_.is_remote_mode);
266 EXPECT_FALSE(options_.use_socket);
267 EXPECT_FALSE(options_.do_start_service);
268}
269
270TEST_F(DumpOptionsTest, InitializeInteractiveBugReport) {
271 // clang-format off
272 char* argv[] = {
273 const_cast<char*>("bugreport"),
274 const_cast<char*>("-d"),
275 const_cast<char*>("-p"),
276 const_cast<char*>("-B"),
277 const_cast<char*>("-z"),
278 const_cast<char*>("-o abc"),
279 };
280 // clang-format on
281
282 property_set("dumpstate.options", "bugreportplus");
283
284 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
285
286 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
287 EXPECT_TRUE(options_.do_add_date);
288 EXPECT_TRUE(options_.do_broadcast);
289 EXPECT_TRUE(options_.do_zip_file);
290 EXPECT_TRUE(options_.do_progress_updates);
291 EXPECT_TRUE(options_.do_start_service);
292 EXPECT_FALSE(options_.do_fb);
293 EXPECT_EQ(" abc", std::string(options_.use_outfile));
294
295 // Other options retain default values
296 EXPECT_TRUE(options_.do_vibrate);
297 EXPECT_FALSE(options_.use_control_socket);
298 EXPECT_FALSE(options_.show_header_only);
299 EXPECT_FALSE(options_.is_remote_mode);
300 EXPECT_FALSE(options_.use_socket);
301}
302
303TEST_F(DumpOptionsTest, InitializeRemoteBugReport) {
304 // clang-format off
305 char* argv[] = {
306 const_cast<char*>("bugreport"),
307 const_cast<char*>("-d"),
308 const_cast<char*>("-p"),
309 const_cast<char*>("-B"),
310 const_cast<char*>("-z"),
311 const_cast<char*>("-o abc"),
312 };
313 // clang-format on
314
315 property_set("dumpstate.options", "bugreportremote");
316
317 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
318
319 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
320 EXPECT_TRUE(options_.do_add_date);
321 EXPECT_TRUE(options_.do_broadcast);
322 EXPECT_TRUE(options_.do_zip_file);
323 EXPECT_TRUE(options_.is_remote_mode);
324 EXPECT_FALSE(options_.do_vibrate);
325 EXPECT_FALSE(options_.do_fb);
326 EXPECT_EQ(" abc", std::string(options_.use_outfile));
327
328 // Other options retain default values
329 EXPECT_FALSE(options_.use_control_socket);
330 EXPECT_FALSE(options_.show_header_only);
331 EXPECT_FALSE(options_.do_progress_updates);
332 EXPECT_FALSE(options_.use_socket);
333}
334
335TEST_F(DumpOptionsTest, InitializeWearBugReport) {
336 // clang-format off
337 char* argv[] = {
338 const_cast<char*>("bugreport"),
339 const_cast<char*>("-d"),
340 const_cast<char*>("-p"),
341 const_cast<char*>("-B"),
342 const_cast<char*>("-z"),
343 const_cast<char*>("-o abc"),
344 };
345 // clang-format on
346
347 property_set("dumpstate.options", "bugreportwear");
348
349 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
350
351 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
352 EXPECT_TRUE(options_.do_add_date);
353 EXPECT_TRUE(options_.do_fb);
354 EXPECT_TRUE(options_.do_broadcast);
355 EXPECT_TRUE(options_.do_zip_file);
356 EXPECT_TRUE(options_.do_progress_updates);
357 EXPECT_TRUE(options_.do_start_service);
358 EXPECT_EQ(" abc", std::string(options_.use_outfile));
359
360 // Other options retain default values
361 EXPECT_TRUE(options_.do_vibrate);
362 EXPECT_FALSE(options_.use_control_socket);
363 EXPECT_FALSE(options_.show_header_only);
364 EXPECT_FALSE(options_.is_remote_mode);
365 EXPECT_FALSE(options_.use_socket);
366}
367
368TEST_F(DumpOptionsTest, InitializeTelephonyBugReport) {
369 // clang-format off
370 char* argv[] = {
371 const_cast<char*>("bugreport"),
372 const_cast<char*>("-d"),
373 const_cast<char*>("-p"),
374 const_cast<char*>("-B"),
375 const_cast<char*>("-z"),
376 const_cast<char*>("-o abc"),
377 };
378 // clang-format on
379
380 property_set("dumpstate.options", "bugreporttelephony");
381
382 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
383
384 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
385 EXPECT_TRUE(options_.do_add_date);
386 EXPECT_TRUE(options_.do_fb);
387 EXPECT_TRUE(options_.do_broadcast);
388 EXPECT_TRUE(options_.do_zip_file);
389 EXPECT_TRUE(options_.telephony_only);
390 EXPECT_EQ(" abc", std::string(options_.use_outfile));
391
392 // Other options retain default values
393 EXPECT_TRUE(options_.do_vibrate);
394 EXPECT_FALSE(options_.use_control_socket);
395 EXPECT_FALSE(options_.show_header_only);
396 EXPECT_FALSE(options_.do_progress_updates);
397 EXPECT_FALSE(options_.is_remote_mode);
398 EXPECT_FALSE(options_.use_socket);
399}
400
401TEST_F(DumpOptionsTest, InitializeWifiBugReport) {
402 // clang-format off
403 char* argv[] = {
404 const_cast<char*>("bugreport"),
405 const_cast<char*>("-d"),
406 const_cast<char*>("-p"),
407 const_cast<char*>("-B"),
408 const_cast<char*>("-z"),
409 const_cast<char*>("-o abc"),
410 };
411 // clang-format on
412
413 property_set("dumpstate.options", "bugreportwifi");
414
415 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
416
417 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
418 EXPECT_TRUE(options_.do_add_date);
419 EXPECT_TRUE(options_.do_fb);
420 EXPECT_TRUE(options_.do_broadcast);
421 EXPECT_TRUE(options_.do_zip_file);
422 EXPECT_TRUE(options_.wifi_only);
423 EXPECT_EQ(" abc", std::string(options_.use_outfile));
424
425 // Other options retain default values
426 EXPECT_TRUE(options_.do_vibrate);
427 EXPECT_FALSE(options_.use_control_socket);
428 EXPECT_FALSE(options_.show_header_only);
429 EXPECT_FALSE(options_.do_progress_updates);
430 EXPECT_FALSE(options_.is_remote_mode);
431 EXPECT_FALSE(options_.use_socket);
432}
433
434TEST_F(DumpOptionsTest, InitializeDefaultBugReport) {
435 // default: commandline options are not overridden
436 // clang-format off
437 char* argv[] = {
438 const_cast<char*>("bugreport"),
439 const_cast<char*>("-d"),
440 const_cast<char*>("-p"),
441 const_cast<char*>("-B"),
442 const_cast<char*>("-z"),
443 const_cast<char*>("-o abc"),
444 };
445 // clang-format on
446
447 property_set("dumpstate.options", "");
448
449 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
450
451 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
452 EXPECT_TRUE(options_.do_add_date);
453 EXPECT_TRUE(options_.do_fb);
454 EXPECT_TRUE(options_.do_zip_file);
455 EXPECT_TRUE(options_.do_broadcast);
456 EXPECT_EQ(" abc", std::string(options_.use_outfile));
457
458 // Other options retain default values
459 EXPECT_TRUE(options_.do_vibrate);
460 EXPECT_FALSE(options_.use_control_socket);
461 EXPECT_FALSE(options_.show_header_only);
462 EXPECT_FALSE(options_.do_progress_updates);
463 EXPECT_FALSE(options_.is_remote_mode);
464 EXPECT_FALSE(options_.use_socket);
465 EXPECT_FALSE(options_.wifi_only);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100466}
467
468TEST_F(DumpOptionsTest, InitializePartial1) {
469 // clang-format off
470 char* argv[] = {
471 const_cast<char*>("dumpstate"),
472 const_cast<char*>("-d"),
473 const_cast<char*>("-z"),
474 const_cast<char*>("-o abc"),
475 const_cast<char*>("-s"),
476 const_cast<char*>("-S"),
477
478 };
479 // clang-format on
480
481 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
482
483 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
484 EXPECT_TRUE(options_.do_add_date);
485 EXPECT_TRUE(options_.do_zip_file);
486 // TODO: Maybe we should trim the filename
487 EXPECT_EQ(" abc", std::string(options_.use_outfile));
488 EXPECT_TRUE(options_.use_socket);
489 EXPECT_TRUE(options_.use_control_socket);
490
491 // Other options retain default values
492 EXPECT_FALSE(options_.show_header_only);
493 EXPECT_TRUE(options_.do_vibrate);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000494 EXPECT_FALSE(options_.do_fb);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100495 EXPECT_FALSE(options_.do_progress_updates);
496 EXPECT_FALSE(options_.is_remote_mode);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000497 EXPECT_FALSE(options_.do_broadcast);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100498}
499
500TEST_F(DumpOptionsTest, InitializePartial2) {
501 // clang-format off
502 char* argv[] = {
503 const_cast<char*>("dumpstate"),
504 const_cast<char*>("-v"),
505 const_cast<char*>("-q"),
506 const_cast<char*>("-p"),
507 const_cast<char*>("-P"),
508 const_cast<char*>("-R"),
509 const_cast<char*>("-B"),
510 };
511 // clang-format on
512
513 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
514
515 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
516 EXPECT_TRUE(options_.show_header_only);
517 EXPECT_FALSE(options_.do_vibrate);
518 EXPECT_TRUE(options_.do_fb);
519 EXPECT_TRUE(options_.do_progress_updates);
520 EXPECT_TRUE(options_.is_remote_mode);
521 EXPECT_TRUE(options_.do_broadcast);
522
523 // Other options retain default values
524 EXPECT_FALSE(options_.do_add_date);
525 EXPECT_FALSE(options_.do_zip_file);
526 EXPECT_EQ("", options_.use_outfile);
527 EXPECT_FALSE(options_.use_socket);
528 EXPECT_FALSE(options_.use_control_socket);
529}
530
531TEST_F(DumpOptionsTest, InitializeHelp) {
532 // clang-format off
533 char* argv[] = {
534 const_cast<char*>("dumpstate"),
535 const_cast<char*>("-h")
536 };
537 // clang-format on
538
539 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
540
541 // -h is for help.
542 EXPECT_EQ(status, Dumpstate::RunStatus::HELP);
543}
544
545TEST_F(DumpOptionsTest, InitializeUnknown) {
546 // clang-format off
547 char* argv[] = {
548 const_cast<char*>("dumpstate"),
549 const_cast<char*>("-u") // unknown flag
550 };
551 // clang-format on
552
553 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
554
555 // -u is unknown.
556 EXPECT_EQ(status, Dumpstate::RunStatus::INVALID_INPUT);
557}
558
559TEST_F(DumpOptionsTest, ValidateOptionsNeedOutfile1) {
560 options_.do_zip_file = true;
561 EXPECT_FALSE(options_.ValidateOptions());
562 options_.use_outfile = "a/b/c";
563 EXPECT_TRUE(options_.ValidateOptions());
564}
565
566TEST_F(DumpOptionsTest, ValidateOptionsNeedOutfile2) {
567 options_.do_broadcast = true;
568 EXPECT_FALSE(options_.ValidateOptions());
569 options_.use_outfile = "a/b/c";
570 EXPECT_TRUE(options_.ValidateOptions());
571}
572
573TEST_F(DumpOptionsTest, ValidateOptionsNeedZipfile) {
574 options_.use_control_socket = true;
575 EXPECT_FALSE(options_.ValidateOptions());
576
577 options_.do_zip_file = true;
578 options_.use_outfile = "a/b/c"; // do_zip_file needs outfile
579 EXPECT_TRUE(options_.ValidateOptions());
580}
581
582TEST_F(DumpOptionsTest, ValidateOptionsUpdateProgressNeedsBroadcast) {
583 options_.do_progress_updates = true;
584 options_.use_outfile = "a/b/c"; // do_progress_updates needs outfile
585 EXPECT_FALSE(options_.ValidateOptions());
586
587 options_.do_broadcast = true;
588 EXPECT_TRUE(options_.ValidateOptions());
589}
590
591TEST_F(DumpOptionsTest, ValidateOptionsRemoteMode) {
592 options_.is_remote_mode = true;
593 EXPECT_FALSE(options_.ValidateOptions());
594
595 options_.do_broadcast = true;
596 options_.do_zip_file = true;
597 options_.do_add_date = true;
598 options_.use_outfile = "a/b/c"; // do_broadcast needs outfile
599 EXPECT_TRUE(options_.ValidateOptions());
600}
601
Felipe Leme7447d7c2016-11-03 18:12:22 -0700602class DumpstateTest : public DumpstateBaseTest {
Felipe Leme4c2d6632016-09-28 14:32:00 -0700603 public:
604 void SetUp() {
Felipe Leme46b85da2016-11-21 17:40:45 -0800605 DumpstateBaseTest::SetUp();
Felipe Leme4c2d6632016-09-28 14:32:00 -0700606 SetDryRun(false);
Felipe Lemed80e6b62016-10-03 13:08:14 -0700607 SetBuildType(android::base::GetProperty("ro.build.type", "(unknown)"));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700608 ds.progress_.reset(new Progress());
Felipe Leme009ecbb2016-11-07 10:18:44 -0800609 ds.update_progress_threshold_ = 0;
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100610 ds.options_.reset(new Dumpstate::DumpOptions());
Felipe Leme4c2d6632016-09-28 14:32:00 -0700611 }
612
613 // Runs a command and capture `stdout` and `stderr`.
Felipe Leme9a523ae2016-10-20 15:10:33 -0700614 int RunCommand(const std::string& title, const std::vector<std::string>& full_command,
Felipe Leme4c2d6632016-09-28 14:32:00 -0700615 const CommandOptions& options = CommandOptions::DEFAULT) {
616 CaptureStdout();
617 CaptureStderr();
Felipe Leme9a523ae2016-10-20 15:10:33 -0700618 int status = ds.RunCommand(title, full_command, options);
Felipe Leme4c2d6632016-09-28 14:32:00 -0700619 out = GetCapturedStdout();
620 err = GetCapturedStderr();
621 return status;
622 }
623
Felipe Lemecef02982016-10-03 17:22:22 -0700624 // Dumps a file and capture `stdout` and `stderr`.
625 int DumpFile(const std::string& title, const std::string& path) {
626 CaptureStdout();
627 CaptureStderr();
628 int status = ds.DumpFile(title, path);
629 out = GetCapturedStdout();
630 err = GetCapturedStderr();
631 return status;
632 }
633
Felipe Leme009ecbb2016-11-07 10:18:44 -0800634 void SetProgress(long progress, long initial_max, long threshold = 0) {
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100635 ds.options_->do_progress_updates = true;
Felipe Leme009ecbb2016-11-07 10:18:44 -0800636 ds.update_progress_threshold_ = threshold;
637 ds.last_updated_progress_ = 0;
Felipe Leme7447d7c2016-11-03 18:12:22 -0700638 ds.progress_.reset(new Progress(initial_max, progress, 1.2));
639 }
640
Felipe Leme7447d7c2016-11-03 18:12:22 -0700641 std::string GetProgressMessage(const std::string& listener_name, int progress, int max,
Felipe Leme009ecbb2016-11-07 10:18:44 -0800642 int old_max = 0, bool update_progress = true) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700643 EXPECT_EQ(progress, ds.progress_->Get()) << "invalid progress";
644 EXPECT_EQ(max, ds.progress_->GetMax()) << "invalid max";
Felipe Leme75876a22016-10-27 16:31:27 -0700645
Felipe Leme7447d7c2016-11-03 18:12:22 -0700646 bool max_increased = old_max > 0;
Felipe Leme75876a22016-10-27 16:31:27 -0700647
Felipe Leme009ecbb2016-11-07 10:18:44 -0800648 std::string message = "";
Felipe Leme75876a22016-10-27 16:31:27 -0700649 if (max_increased) {
Felipe Leme009ecbb2016-11-07 10:18:44 -0800650 message =
Felipe Leme7447d7c2016-11-03 18:12:22 -0700651 android::base::StringPrintf("Adjusting max progress from %d to %d\n", old_max, max);
Felipe Leme75876a22016-10-27 16:31:27 -0700652 }
653
Felipe Leme009ecbb2016-11-07 10:18:44 -0800654 if (update_progress) {
655 message += android::base::StringPrintf("Setting progress (%s): %d/%d\n",
656 listener_name.c_str(), progress, max);
657 }
658
659 return message;
Felipe Lemed80e6b62016-10-03 13:08:14 -0700660 }
661
Felipe Leme4c2d6632016-09-28 14:32:00 -0700662 // `stdout` and `stderr` from the last command ran.
663 std::string out, err;
664
Felipe Lemefd8affa2016-09-30 17:38:57 -0700665 Dumpstate& ds = Dumpstate::GetInstance();
Felipe Leme4c2d6632016-09-28 14:32:00 -0700666};
667
668TEST_F(DumpstateTest, RunCommandNoArgs) {
669 EXPECT_EQ(-1, RunCommand("", {}));
670}
671
672TEST_F(DumpstateTest, RunCommandNoTitle) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700673 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700674 EXPECT_THAT(out, StrEq("stdout\n"));
675 EXPECT_THAT(err, StrEq("stderr\n"));
676}
677
678TEST_F(DumpstateTest, RunCommandWithTitle) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700679 EXPECT_EQ(0, RunCommand("I AM GROOT", {kSimpleCommand}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700680 EXPECT_THAT(err, StrEq("stderr\n"));
681 // We don't know the exact duration, so we check the prefix and suffix
Felipe Lemefd8affa2016-09-30 17:38:57 -0700682 EXPECT_THAT(out,
Felipe Leme7447d7c2016-11-03 18:12:22 -0700683 StartsWith("------ I AM GROOT (" + kSimpleCommand + ") ------\nstdout\n------"));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700684 EXPECT_THAT(out, EndsWith("s was the duration of 'I AM GROOT' ------\n"));
685}
686
Felipe Lemefd8affa2016-09-30 17:38:57 -0700687TEST_F(DumpstateTest, RunCommandWithLoggingMessage) {
Felipe Leme4c2d6632016-09-28 14:32:00 -0700688 EXPECT_EQ(
Felipe Leme7447d7c2016-11-03 18:12:22 -0700689 0, RunCommand("", {kSimpleCommand},
Felipe Lemefd8affa2016-09-30 17:38:57 -0700690 CommandOptions::WithTimeout(10).Log("COMMAND, Y U NO LOG FIRST?").Build()));
691 EXPECT_THAT(out, StrEq("stdout\n"));
692 EXPECT_THAT(err, StrEq("COMMAND, Y U NO LOG FIRST?stderr\n"));
693}
694
695TEST_F(DumpstateTest, RunCommandRedirectStderr) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700696 EXPECT_EQ(0, RunCommand("", {kSimpleCommand},
Felipe Lemefd8affa2016-09-30 17:38:57 -0700697 CommandOptions::WithTimeout(10).RedirectStderr().Build()));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700698 EXPECT_THAT(out, IsEmpty());
Felipe Lemefd8affa2016-09-30 17:38:57 -0700699 EXPECT_THAT(err, StrEq("stdout\nstderr\n"));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700700}
701
702TEST_F(DumpstateTest, RunCommandWithOneArg) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700703 EXPECT_EQ(0, RunCommand("", {kEchoCommand, "one"}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700704 EXPECT_THAT(err, IsEmpty());
705 EXPECT_THAT(out, StrEq("one\n"));
706}
707
Felipe Lemefd8affa2016-09-30 17:38:57 -0700708TEST_F(DumpstateTest, RunCommandWithMultipleArgs) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700709 EXPECT_EQ(0, RunCommand("", {kEchoCommand, "one", "is", "the", "loniest", "number"}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700710 EXPECT_THAT(err, IsEmpty());
711 EXPECT_THAT(out, StrEq("one is the loniest number\n"));
712}
713
714TEST_F(DumpstateTest, RunCommandDryRun) {
715 SetDryRun(true);
Felipe Leme7447d7c2016-11-03 18:12:22 -0700716 EXPECT_EQ(0, RunCommand("I AM GROOT", {kSimpleCommand}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700717 // We don't know the exact duration, so we check the prefix and suffix
Felipe Leme7447d7c2016-11-03 18:12:22 -0700718 EXPECT_THAT(out, StartsWith("------ I AM GROOT (" + kSimpleCommand +
Felipe Leme4c2d6632016-09-28 14:32:00 -0700719 ") ------\n\t(skipped on dry run)\n------"));
720 EXPECT_THAT(out, EndsWith("s was the duration of 'I AM GROOT' ------\n"));
721 EXPECT_THAT(err, IsEmpty());
722}
723
724TEST_F(DumpstateTest, RunCommandDryRunNoTitle) {
725 SetDryRun(true);
Felipe Leme7447d7c2016-11-03 18:12:22 -0700726 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700727 EXPECT_THAT(out, IsEmpty());
728 EXPECT_THAT(err, IsEmpty());
729}
730
731TEST_F(DumpstateTest, RunCommandDryRunAlways) {
732 SetDryRun(true);
Felipe Leme7447d7c2016-11-03 18:12:22 -0700733 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(10).Always().Build()));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700734 EXPECT_THAT(out, StrEq("stdout\n"));
735 EXPECT_THAT(err, StrEq("stderr\n"));
736}
737
Felipe Lemefd8affa2016-09-30 17:38:57 -0700738TEST_F(DumpstateTest, RunCommandNotFound) {
739 EXPECT_NE(0, RunCommand("", {"/there/cannot/be/such/command"}));
740 EXPECT_THAT(out, StartsWith("*** command '/there/cannot/be/such/command' failed: exit code"));
741 EXPECT_THAT(err, StartsWith("execvp on command '/there/cannot/be/such/command' failed"));
742}
743
744TEST_F(DumpstateTest, RunCommandFails) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700745 EXPECT_EQ(42, RunCommand("", {kSimpleCommand, "--exit", "42"}));
746 EXPECT_THAT(out, StrEq("stdout\n*** command '" + kSimpleCommand +
Felipe Leme9a523ae2016-10-20 15:10:33 -0700747 " --exit 42' failed: exit code 42\n"));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700748 EXPECT_THAT(err, StrEq("stderr\n*** command '" + kSimpleCommand +
Felipe Leme9a523ae2016-10-20 15:10:33 -0700749 " --exit 42' failed: exit code 42\n"));
Felipe Lemefd8affa2016-09-30 17:38:57 -0700750}
751
752TEST_F(DumpstateTest, RunCommandCrashes) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700753 EXPECT_NE(0, RunCommand("", {kSimpleCommand, "--crash"}));
Felipe Lemefd8affa2016-09-30 17:38:57 -0700754 // We don't know the exit code, so check just the prefix.
755 EXPECT_THAT(
Felipe Leme7447d7c2016-11-03 18:12:22 -0700756 out, StartsWith("stdout\n*** command '" + kSimpleCommand + " --crash' failed: exit code"));
Felipe Lemefd8affa2016-09-30 17:38:57 -0700757 EXPECT_THAT(
Felipe Leme7447d7c2016-11-03 18:12:22 -0700758 err, StartsWith("stderr\n*** command '" + kSimpleCommand + " --crash' failed: exit code"));
Felipe Lemefd8affa2016-09-30 17:38:57 -0700759}
760
761TEST_F(DumpstateTest, RunCommandTimesout) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700762 EXPECT_EQ(-1, RunCommand("", {kSimpleCommand, "--sleep", "2"},
Felipe Lemefd8affa2016-09-30 17:38:57 -0700763 CommandOptions::WithTimeout(1).Build()));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700764 EXPECT_THAT(out, StartsWith("stdout line1\n*** command '" + kSimpleCommand +
Felipe Lemefd8affa2016-09-30 17:38:57 -0700765 " --sleep 2' timed out after 1"));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700766 EXPECT_THAT(err, StartsWith("sleeping for 2s\n*** command '" + kSimpleCommand +
Felipe Lemefd8affa2016-09-30 17:38:57 -0700767 " --sleep 2' timed out after 1"));
768}
769
770TEST_F(DumpstateTest, RunCommandIsKilled) {
771 CaptureStdout();
772 CaptureStderr();
773
774 std::thread t([=]() {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700775 EXPECT_EQ(SIGTERM, ds.RunCommand("", {kSimpleCommand, "--pid", "--sleep", "20"},
Felipe Lemefd8affa2016-09-30 17:38:57 -0700776 CommandOptions::WithTimeout(100).Always().Build()));
777 });
778
779 // Capture pid and pre-sleep output.
780 sleep(1); // Wait a little bit to make sure pid and 1st line were printed.
781 std::string err = GetCapturedStderr();
782 EXPECT_THAT(err, StrEq("sleeping for 20s\n"));
783
784 std::string out = GetCapturedStdout();
785 std::vector<std::string> lines = android::base::Split(out, "\n");
786 ASSERT_EQ(3, (int)lines.size()) << "Invalid lines before sleep: " << out;
787
788 int pid = atoi(lines[0].c_str());
789 EXPECT_THAT(lines[1], StrEq("stdout line1"));
790 EXPECT_THAT(lines[2], IsEmpty()); // \n
791
792 // Then kill the process.
793 CaptureStdout();
794 CaptureStderr();
795 ASSERT_EQ(0, kill(pid, SIGTERM)) << "failed to kill pid " << pid;
796 t.join();
797
798 // Finally, check output after murder.
799 out = GetCapturedStdout();
800 err = GetCapturedStderr();
801
Felipe Leme7447d7c2016-11-03 18:12:22 -0700802 EXPECT_THAT(out, StrEq("*** command '" + kSimpleCommand +
Felipe Lemefd8affa2016-09-30 17:38:57 -0700803 " --pid --sleep 20' failed: killed by signal 15\n"));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700804 EXPECT_THAT(err, StrEq("*** command '" + kSimpleCommand +
Felipe Lemefd8affa2016-09-30 17:38:57 -0700805 " --pid --sleep 20' failed: killed by signal 15\n"));
806}
807
Felipe Leme75876a22016-10-27 16:31:27 -0700808TEST_F(DumpstateTest, RunCommandProgress) {
809 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
810 ds.listener_ = listener;
811 ds.listener_name_ = "FoxMulder";
Felipe Leme7447d7c2016-11-03 18:12:22 -0700812 SetProgress(0, 30);
Felipe Leme75876a22016-10-27 16:31:27 -0700813
814 EXPECT_CALL(*listener, onProgressUpdated(20));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700815 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(20).Build()));
Felipe Leme75876a22016-10-27 16:31:27 -0700816 std::string progress_message = GetProgressMessage(ds.listener_name_, 20, 30);
817 EXPECT_THAT(out, StrEq("stdout\n"));
818 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
819
820 EXPECT_CALL(*listener, onProgressUpdated(30));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700821 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(10).Build()));
Felipe Leme75876a22016-10-27 16:31:27 -0700822 progress_message = GetProgressMessage(ds.listener_name_, 30, 30);
823 EXPECT_THAT(out, StrEq("stdout\n"));
824 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
825
826 // Run a command that will increase maximum timeout.
827 EXPECT_CALL(*listener, onProgressUpdated(31));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700828 EXPECT_CALL(*listener, onMaxProgressUpdated(37));
829 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).Build()));
830 progress_message = GetProgressMessage(ds.listener_name_, 31, 37, 30); // 20% increase
Felipe Leme75876a22016-10-27 16:31:27 -0700831 EXPECT_THAT(out, StrEq("stdout\n"));
832 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
833
834 // Make sure command ran while in dry_run is counted.
835 SetDryRun(true);
836 EXPECT_CALL(*listener, onProgressUpdated(35));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700837 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(4).Build()));
838 progress_message = GetProgressMessage(ds.listener_name_, 35, 37);
Felipe Leme75876a22016-10-27 16:31:27 -0700839 EXPECT_THAT(out, IsEmpty());
840 EXPECT_THAT(err, StrEq(progress_message));
841
842 ds.listener_.clear();
843}
844
Felipe Leme009ecbb2016-11-07 10:18:44 -0800845TEST_F(DumpstateTest, RunCommandProgressIgnoreThreshold) {
846 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
847 ds.listener_ = listener;
848 ds.listener_name_ = "FoxMulder";
849 SetProgress(0, 8, 5); // 8 max, 5 threshold
850
851 // First update should always be sent.
852 EXPECT_CALL(*listener, onProgressUpdated(1));
853 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).Build()));
854 std::string progress_message = GetProgressMessage(ds.listener_name_, 1, 8);
855 EXPECT_THAT(out, StrEq("stdout\n"));
856 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
857
858 // Fourth update should be ignored because it's between the threshold (5 -1 = 4 < 5).
859 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(4).Build()));
860 EXPECT_THAT(out, StrEq("stdout\n"));
861 EXPECT_THAT(err, StrEq("stderr\n"));
862
863 // Third update should be sent because it reaches threshold (6 - 1 = 5).
864 EXPECT_CALL(*listener, onProgressUpdated(6));
865 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).Build()));
866 progress_message = GetProgressMessage(ds.listener_name_, 6, 8);
867 EXPECT_THAT(out, StrEq("stdout\n"));
868 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
869
870 // Fourth update should be ignored because it's between the threshold (9 - 6 = 3 < 5).
871 // But max update should be sent.
872 EXPECT_CALL(*listener, onMaxProgressUpdated(10)); // 9 * 120% = 10.8 = 10
873 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(3).Build()));
874 progress_message = GetProgressMessage(ds.listener_name_, 9, 10, 8, false);
875 EXPECT_THAT(out, StrEq("stdout\n"));
876 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
877
878 ds.listener_.clear();
879}
880
Felipe Lemed80e6b62016-10-03 13:08:14 -0700881TEST_F(DumpstateTest, RunCommandDropRoot) {
Felipe Leme46b85da2016-11-21 17:40:45 -0800882 if (!IsStandalone()) {
883 // TODO: temporarily disabled because it might cause other tests to fail after dropping
884 // to Shell - need to refactor tests to avoid this problem)
885 MYLOGE("Skipping DumpstateTest.RunCommandDropRoot() on test suite\n")
886 return;
887 }
Felipe Lemed80e6b62016-10-03 13:08:14 -0700888 // First check root case - only available when running with 'adb root'.
889 uid_t uid = getuid();
890 if (uid == 0) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700891 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"}));
Felipe Lemed80e6b62016-10-03 13:08:14 -0700892 EXPECT_THAT(out, StrEq("0\nstdout\n"));
893 EXPECT_THAT(err, StrEq("stderr\n"));
894 return;
895 }
Felipe Leme7447d7c2016-11-03 18:12:22 -0700896 // Then run dropping root.
897 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
Felipe Lemed80e6b62016-10-03 13:08:14 -0700898 CommandOptions::WithTimeout(1).DropRoot().Build()));
899 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
Felipe Leme26c41572016-10-06 14:34:43 -0700900 EXPECT_THAT(err, StrEq("drop_root_user(): already running as Shell\nstderr\n"));
Felipe Lemed80e6b62016-10-03 13:08:14 -0700901}
902
903TEST_F(DumpstateTest, RunCommandAsRootUserBuild) {
Felipe Leme46b85da2016-11-21 17:40:45 -0800904 if (!IsStandalone()) {
905 // TODO: temporarily disabled because it might cause other tests to fail after dropping
906 // to Shell - need to refactor tests to avoid this problem)
907 MYLOGE("Skipping DumpstateTest.RunCommandAsRootUserBuild() on test suite\n")
908 return;
909 }
Felipe Lemef0292972016-11-22 13:57:05 -0800910 if (!PropertiesHelper::IsUserBuild()) {
Felipe Lemed80e6b62016-10-03 13:08:14 -0700911 // Emulates user build if necessarily.
912 SetBuildType("user");
913 }
914
915 DropRoot();
916
Felipe Leme7447d7c2016-11-03 18:12:22 -0700917 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).AsRoot().Build()));
Felipe Lemed80e6b62016-10-03 13:08:14 -0700918
919 // We don't know the exact path of su, so we just check for the 'root ...' commands
920 EXPECT_THAT(out, StartsWith("Skipping"));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700921 EXPECT_THAT(out, EndsWith("root " + kSimpleCommand + "' on user build.\n"));
Felipe Lemed80e6b62016-10-03 13:08:14 -0700922 EXPECT_THAT(err, IsEmpty());
923}
924
Felipe Leme46b85da2016-11-21 17:40:45 -0800925TEST_F(DumpstateTest, RunCommandAsRootNonUserBuild) {
926 if (!IsStandalone()) {
927 // TODO: temporarily disabled because it might cause other tests to fail after dropping
928 // to Shell - need to refactor tests to avoid this problem)
929 MYLOGE("Skipping DumpstateTest.RunCommandAsRootNonUserBuild() on test suite\n")
930 return;
931 }
Felipe Lemef0292972016-11-22 13:57:05 -0800932 if (PropertiesHelper::IsUserBuild()) {
Felipe Leme46b85da2016-11-21 17:40:45 -0800933 ALOGI("Skipping RunCommandAsRootNonUserBuild on user builds\n");
934 return;
935 }
936
937 DropRoot();
938
939 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
940 CommandOptions::WithTimeout(1).AsRoot().Build()));
941
942 EXPECT_THAT(out, StrEq("0\nstdout\n"));
943 EXPECT_THAT(err, StrEq("stderr\n"));
944}
945
Nandana Dutt4b392be2018-11-02 16:17:05 +0000946TEST_F(DumpstateTest, RunCommandAsRootNonUserBuild_withUnroot) {
947 if (!IsStandalone()) {
948 // TODO: temporarily disabled because it might cause other tests to fail after dropping
949 // to Shell - need to refactor tests to avoid this problem)
950 MYLOGE(
951 "Skipping DumpstateTest.RunCommandAsRootNonUserBuild_withUnroot() "
952 "on test suite\n")
953 return;
954 }
955 if (PropertiesHelper::IsUserBuild()) {
956 ALOGI("Skipping RunCommandAsRootNonUserBuild_withUnroot on user builds\n");
957 return;
958 }
959
960 // Same test as above, but with unroot property set, which will override su availability.
961 SetUnroot(true);
962 DropRoot();
963
964 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
965 CommandOptions::WithTimeout(1).AsRoot().Build()));
966
967 // AsRoot is ineffective.
968 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
969 EXPECT_THAT(err, StrEq("drop_root_user(): already running as Shell\nstderr\n"));
970}
971
Yifan Hong48e83a12017-10-03 14:10:07 -0700972TEST_F(DumpstateTest, RunCommandAsRootIfAvailableOnUserBuild) {
973 if (!IsStandalone()) {
974 // TODO: temporarily disabled because it might cause other tests to fail after dropping
975 // to Shell - need to refactor tests to avoid this problem)
976 MYLOGE("Skipping DumpstateTest.RunCommandAsRootIfAvailableOnUserBuild() on test suite\n")
977 return;
978 }
979 if (!PropertiesHelper::IsUserBuild()) {
980 // Emulates user build if necessarily.
981 SetBuildType("user");
982 }
983
984 DropRoot();
985
986 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
987 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
988
989 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
990 EXPECT_THAT(err, StrEq("stderr\n"));
991}
992
993TEST_F(DumpstateTest, RunCommandAsRootIfAvailableOnDebugBuild) {
994 if (!IsStandalone()) {
995 // TODO: temporarily disabled because it might cause other tests to fail after dropping
996 // to Shell - need to refactor tests to avoid this problem)
997 MYLOGE("Skipping DumpstateTest.RunCommandAsRootIfAvailableOnDebugBuild() on test suite\n")
998 return;
999 }
1000 if (PropertiesHelper::IsUserBuild()) {
1001 ALOGI("Skipping RunCommandAsRootNonUserBuild on user builds\n");
1002 return;
1003 }
1004
1005 DropRoot();
1006
1007 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
1008 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
1009
1010 EXPECT_THAT(out, StrEq("0\nstdout\n"));
1011 EXPECT_THAT(err, StrEq("stderr\n"));
1012}
1013
Nandana Dutt4b392be2018-11-02 16:17:05 +00001014TEST_F(DumpstateTest, RunCommandAsRootIfAvailableOnDebugBuild_withUnroot) {
1015 if (!IsStandalone()) {
1016 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1017 // to Shell - need to refactor tests to avoid this problem)
1018 MYLOGE(
1019 "Skipping DumpstateTest.RunCommandAsRootIfAvailableOnDebugBuild_withUnroot() "
1020 "on test suite\n")
1021 return;
1022 }
1023 if (PropertiesHelper::IsUserBuild()) {
1024 ALOGI("Skipping RunCommandAsRootIfAvailableOnDebugBuild_withUnroot on user builds\n");
1025 return;
1026 }
1027 // Same test as above, but with unroot property set, which will override su availability.
1028 SetUnroot(true);
1029
1030 DropRoot();
1031
1032 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
1033 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
1034
1035 // It's a userdebug build, so "su root" should be available, but unroot=true overrides it.
1036 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
1037 EXPECT_THAT(err, StrEq("stderr\n"));
1038}
1039
Felipe Lemecef02982016-10-03 17:22:22 -07001040TEST_F(DumpstateTest, DumpFileNotFoundNoTitle) {
1041 EXPECT_EQ(-1, DumpFile("", "/I/cant/believe/I/exist"));
1042 EXPECT_THAT(out,
1043 StrEq("*** Error dumping /I/cant/believe/I/exist: No such file or directory\n"));
1044 EXPECT_THAT(err, IsEmpty());
1045}
1046
1047TEST_F(DumpstateTest, DumpFileNotFoundWithTitle) {
1048 EXPECT_EQ(-1, DumpFile("Y U NO EXIST?", "/I/cant/believe/I/exist"));
1049 EXPECT_THAT(err, IsEmpty());
1050 // We don't know the exact duration, so we check the prefix and suffix
1051 EXPECT_THAT(out, StartsWith("*** Error dumping /I/cant/believe/I/exist (Y U NO EXIST?): No "
1052 "such file or directory\n"));
1053 EXPECT_THAT(out, EndsWith("s was the duration of 'Y U NO EXIST?' ------\n"));
1054}
1055
1056TEST_F(DumpstateTest, DumpFileSingleLine) {
Felipe Leme7447d7c2016-11-03 18:12:22 -07001057 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -07001058 EXPECT_THAT(err, IsEmpty());
1059 EXPECT_THAT(out, StrEq("I AM LINE1\n")); // dumpstate adds missing newline
1060}
1061
1062TEST_F(DumpstateTest, DumpFileSingleLineWithNewLine) {
Felipe Leme7447d7c2016-11-03 18:12:22 -07001063 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line-with-newline.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -07001064 EXPECT_THAT(err, IsEmpty());
1065 EXPECT_THAT(out, StrEq("I AM LINE1\n"));
1066}
1067
1068TEST_F(DumpstateTest, DumpFileMultipleLines) {
Felipe Leme7447d7c2016-11-03 18:12:22 -07001069 EXPECT_EQ(0, DumpFile("", kTestDataPath + "multiple-lines.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -07001070 EXPECT_THAT(err, IsEmpty());
1071 EXPECT_THAT(out, StrEq("I AM LINE1\nI AM LINE2\nI AM LINE3\n"));
1072}
1073
1074TEST_F(DumpstateTest, DumpFileMultipleLinesWithNewLine) {
Felipe Leme7447d7c2016-11-03 18:12:22 -07001075 EXPECT_EQ(0, DumpFile("", kTestDataPath + "multiple-lines-with-newline.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -07001076 EXPECT_THAT(err, IsEmpty());
1077 EXPECT_THAT(out, StrEq("I AM LINE1\nI AM LINE2\nI AM LINE3\n"));
1078}
1079
1080TEST_F(DumpstateTest, DumpFileOnDryRunNoTitle) {
1081 SetDryRun(true);
Felipe Leme7447d7c2016-11-03 18:12:22 -07001082 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -07001083 EXPECT_THAT(err, IsEmpty());
1084 EXPECT_THAT(out, IsEmpty());
1085}
1086
1087TEST_F(DumpstateTest, DumpFileOnDryRun) {
1088 SetDryRun(true);
Felipe Leme7447d7c2016-11-03 18:12:22 -07001089 EXPECT_EQ(0, DumpFile("Might as well dump. Dump!", kTestDataPath + "single-line.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -07001090 EXPECT_THAT(err, IsEmpty());
Felipe Leme46b85da2016-11-21 17:40:45 -08001091 EXPECT_THAT(
1092 out, StartsWith("------ Might as well dump. Dump! (" + kTestDataPath + "single-line.txt:"));
1093 EXPECT_THAT(out, HasSubstr("\n\t(skipped on dry run)\n------"));
Felipe Lemecef02982016-10-03 17:22:22 -07001094 EXPECT_THAT(out, EndsWith("s was the duration of 'Might as well dump. Dump!' ------\n"));
Felipe Lemecef02982016-10-03 17:22:22 -07001095}
1096
Felipe Leme75876a22016-10-27 16:31:27 -07001097TEST_F(DumpstateTest, DumpFileUpdateProgress) {
1098 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
1099 ds.listener_ = listener;
1100 ds.listener_name_ = "FoxMulder";
Felipe Leme7447d7c2016-11-03 18:12:22 -07001101 SetProgress(0, 30);
Felipe Leme75876a22016-10-27 16:31:27 -07001102
1103 EXPECT_CALL(*listener, onProgressUpdated(5));
Felipe Leme7447d7c2016-11-03 18:12:22 -07001104 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
Felipe Leme75876a22016-10-27 16:31:27 -07001105
1106 std::string progress_message =
1107 GetProgressMessage(ds.listener_name_, 5, 30); // TODO: unhardcode WEIGHT_FILE (5)?
1108 EXPECT_THAT(err, StrEq(progress_message));
1109 EXPECT_THAT(out, StrEq("I AM LINE1\n")); // dumpstate adds missing newline
1110
1111 ds.listener_.clear();
1112}
1113
Felipe Leme7447d7c2016-11-03 18:12:22 -07001114class DumpstateServiceTest : public DumpstateBaseTest {
Felipe Leme75876a22016-10-27 16:31:27 -07001115 public:
1116 DumpstateService dss;
1117};
1118
1119TEST_F(DumpstateServiceTest, SetListenerNoName) {
1120 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
Felipe Leme009ecbb2016-11-07 10:18:44 -08001121 sp<IDumpstateToken> token;
Vishnu Nair20cf5032018-01-05 13:15:49 -08001122 EXPECT_TRUE(dss.setListener("", listener, /* getSectionDetails = */ false, &token).isOk());
Felipe Leme009ecbb2016-11-07 10:18:44 -08001123 ASSERT_THAT(token, IsNull());
Felipe Leme75876a22016-10-27 16:31:27 -07001124}
1125
1126TEST_F(DumpstateServiceTest, SetListenerNoPointer) {
Felipe Leme009ecbb2016-11-07 10:18:44 -08001127 sp<IDumpstateToken> token;
Vishnu Nair20cf5032018-01-05 13:15:49 -08001128 EXPECT_TRUE(
1129 dss.setListener("whatever", nullptr, /* getSectionDetails = */ false, &token).isOk());
Felipe Leme009ecbb2016-11-07 10:18:44 -08001130 ASSERT_THAT(token, IsNull());
Felipe Leme75876a22016-10-27 16:31:27 -07001131}
1132
1133TEST_F(DumpstateServiceTest, SetListenerTwice) {
1134 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
Felipe Leme009ecbb2016-11-07 10:18:44 -08001135 sp<IDumpstateToken> token;
Vishnu Nair20cf5032018-01-05 13:15:49 -08001136 EXPECT_TRUE(
1137 dss.setListener("whatever", listener, /* getSectionDetails = */ false, &token).isOk());
Felipe Leme009ecbb2016-11-07 10:18:44 -08001138 ASSERT_THAT(token, NotNull());
Felipe Leme75876a22016-10-27 16:31:27 -07001139 EXPECT_THAT(Dumpstate::GetInstance().listener_name_, StrEq("whatever"));
Vishnu Nair20cf5032018-01-05 13:15:49 -08001140 EXPECT_FALSE(Dumpstate::GetInstance().report_section_);
Felipe Leme75876a22016-10-27 16:31:27 -07001141
Felipe Leme009ecbb2016-11-07 10:18:44 -08001142 token.clear();
Vishnu Nair20cf5032018-01-05 13:15:49 -08001143 EXPECT_TRUE(
1144 dss.setListener("whatsoever", listener, /* getSectionDetails = */ false, &token).isOk());
Felipe Leme009ecbb2016-11-07 10:18:44 -08001145 ASSERT_THAT(token, IsNull());
1146 EXPECT_THAT(Dumpstate::GetInstance().listener_name_, StrEq("whatever"));
Vishnu Nair20cf5032018-01-05 13:15:49 -08001147 EXPECT_FALSE(Dumpstate::GetInstance().report_section_);
1148}
1149
1150TEST_F(DumpstateServiceTest, SetListenerWithSectionDetails) {
1151 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
1152 sp<IDumpstateToken> token;
1153 Dumpstate::GetInstance().listener_ = nullptr;
1154 EXPECT_TRUE(
1155 dss.setListener("whatever", listener, /* getSectionDetails = */ true, &token).isOk());
1156 ASSERT_THAT(token, NotNull());
1157 EXPECT_THAT(Dumpstate::GetInstance().listener_name_, StrEq("whatever"));
1158 EXPECT_TRUE(Dumpstate::GetInstance().report_section_);
Felipe Leme75876a22016-10-27 16:31:27 -07001159}
Felipe Leme7447d7c2016-11-03 18:12:22 -07001160
1161class ProgressTest : public DumpstateBaseTest {
1162 public:
1163 Progress GetInstance(int32_t max, double growth_factor, const std::string& path = "") {
1164 return Progress(max, growth_factor, path);
1165 }
1166
1167 void AssertStats(const std::string& path, int32_t expected_runs, int32_t expected_average) {
1168 std::string expected_content =
1169 android::base::StringPrintf("%d %d\n", expected_runs, expected_average);
1170 std::string actual_content;
Felipe Leme46b85da2016-11-21 17:40:45 -08001171 ReadFileToString(path, &actual_content);
Felipe Leme7447d7c2016-11-03 18:12:22 -07001172 ASSERT_THAT(actual_content, StrEq(expected_content)) << "invalid stats on " << path;
1173 }
1174};
1175
1176TEST_F(ProgressTest, SimpleTest) {
1177 Progress progress;
1178 EXPECT_EQ(0, progress.Get());
1179 EXPECT_EQ(Progress::kDefaultMax, progress.GetInitialMax());
1180 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1181
1182 bool max_increased = progress.Inc(1);
1183 EXPECT_EQ(1, progress.Get());
1184 EXPECT_EQ(Progress::kDefaultMax, progress.GetInitialMax());
1185 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1186 EXPECT_FALSE(max_increased);
1187
1188 // Ignore negative increase.
1189 max_increased = progress.Inc(-1);
1190 EXPECT_EQ(1, progress.Get());
1191 EXPECT_EQ(Progress::kDefaultMax, progress.GetInitialMax());
1192 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1193 EXPECT_FALSE(max_increased);
1194}
1195
1196TEST_F(ProgressTest, MaxGrowsInsideNewRange) {
1197 Progress progress = GetInstance(10, 1.2); // 20% growth factor
1198 EXPECT_EQ(0, progress.Get());
1199 EXPECT_EQ(10, progress.GetInitialMax());
1200 EXPECT_EQ(10, progress.GetMax());
1201
1202 // No increase
1203 bool max_increased = progress.Inc(10);
1204 EXPECT_EQ(10, progress.Get());
1205 EXPECT_EQ(10, progress.GetMax());
1206 EXPECT_FALSE(max_increased);
1207
1208 // Increase, with new value < max*20%
1209 max_increased = progress.Inc(1);
1210 EXPECT_EQ(11, progress.Get());
1211 EXPECT_EQ(13, progress.GetMax()); // 11 average * 20% growth = 13.2 = 13
1212 EXPECT_TRUE(max_increased);
1213}
1214
1215TEST_F(ProgressTest, MaxGrowsOutsideNewRange) {
1216 Progress progress = GetInstance(10, 1.2); // 20% growth factor
1217 EXPECT_EQ(0, progress.Get());
1218 EXPECT_EQ(10, progress.GetInitialMax());
1219 EXPECT_EQ(10, progress.GetMax());
1220
1221 // No increase
1222 bool max_increased = progress.Inc(10);
1223 EXPECT_EQ(10, progress.Get());
1224 EXPECT_EQ(10, progress.GetMax());
1225 EXPECT_FALSE(max_increased);
1226
1227 // Increase, with new value > max*20%
1228 max_increased = progress.Inc(5);
1229 EXPECT_EQ(15, progress.Get());
1230 EXPECT_EQ(18, progress.GetMax()); // 15 average * 20% growth = 18
1231 EXPECT_TRUE(max_increased);
1232}
1233
1234TEST_F(ProgressTest, InvalidPath) {
1235 Progress progress("/devil/null");
1236 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1237}
1238
1239TEST_F(ProgressTest, EmptyFile) {
1240 Progress progress(CopyTextFileFixture("empty-file.txt"));
1241 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1242}
1243
1244TEST_F(ProgressTest, InvalidLine1stEntryNAN) {
1245 Progress progress(CopyTextFileFixture("stats-invalid-1st-NAN.txt"));
1246 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1247}
1248
1249TEST_F(ProgressTest, InvalidLine2ndEntryNAN) {
1250 Progress progress(CopyTextFileFixture("stats-invalid-2nd-NAN.txt"));
1251 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1252}
1253
1254TEST_F(ProgressTest, InvalidLineBothNAN) {
1255 Progress progress(CopyTextFileFixture("stats-invalid-both-NAN.txt"));
1256 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1257}
1258
1259TEST_F(ProgressTest, InvalidLine1stEntryNegative) {
1260 Progress progress(CopyTextFileFixture("stats-invalid-1st-negative.txt"));
1261 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1262}
1263
1264TEST_F(ProgressTest, InvalidLine2ndEntryNegative) {
1265 Progress progress(CopyTextFileFixture("stats-invalid-2nd-negative.txt"));
1266 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1267}
1268
1269TEST_F(ProgressTest, InvalidLine1stEntryTooBig) {
1270 Progress progress(CopyTextFileFixture("stats-invalid-1st-too-big.txt"));
1271 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1272}
1273
1274TEST_F(ProgressTest, InvalidLine2ndEntryTooBig) {
1275 Progress progress(CopyTextFileFixture("stats-invalid-2nd-too-big.txt"));
1276 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1277}
1278
1279// Tests stats are properly saved when the file does not exists.
1280TEST_F(ProgressTest, FirstTime) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001281 if (!IsStandalone()) {
1282 // TODO: temporarily disabled because it's failing when running as suite
1283 MYLOGE("Skipping ProgressTest.FirstTime() on test suite\n")
1284 return;
1285 }
1286
Felipe Leme7447d7c2016-11-03 18:12:22 -07001287 std::string path = kTestDataPath + "FirstTime.txt";
1288 android::base::RemoveFileIfExists(path);
1289
1290 Progress run1(path);
1291 EXPECT_EQ(0, run1.Get());
1292 EXPECT_EQ(Progress::kDefaultMax, run1.GetInitialMax());
1293 EXPECT_EQ(Progress::kDefaultMax, run1.GetMax());
1294
1295 bool max_increased = run1.Inc(20);
1296 EXPECT_EQ(20, run1.Get());
1297 EXPECT_EQ(Progress::kDefaultMax, run1.GetMax());
1298 EXPECT_FALSE(max_increased);
1299
1300 run1.Save();
1301 AssertStats(path, 1, 20);
1302}
1303
1304// Tests what happens when the persistent settings contains the average duration of 1 run.
1305// Data on file is 1 run and 109 average.
1306TEST_F(ProgressTest, SecondTime) {
1307 std::string path = CopyTextFileFixture("stats-one-run-no-newline.txt");
1308
1309 Progress run1 = GetInstance(-42, 1.2, path);
1310 EXPECT_EQ(0, run1.Get());
1311 EXPECT_EQ(10, run1.GetInitialMax());
1312 EXPECT_EQ(10, run1.GetMax());
1313
1314 bool max_increased = run1.Inc(20);
1315 EXPECT_EQ(20, run1.Get());
1316 EXPECT_EQ(24, run1.GetMax());
1317 EXPECT_TRUE(max_increased);
1318
1319 // Average now is 2 runs and (10 + 20)/ 2 = 15
1320 run1.Save();
1321 AssertStats(path, 2, 15);
1322
1323 Progress run2 = GetInstance(-42, 1.2, path);
1324 EXPECT_EQ(0, run2.Get());
1325 EXPECT_EQ(15, run2.GetInitialMax());
1326 EXPECT_EQ(15, run2.GetMax());
1327
1328 max_increased = run2.Inc(25);
1329 EXPECT_EQ(25, run2.Get());
1330 EXPECT_EQ(30, run2.GetMax());
1331 EXPECT_TRUE(max_increased);
1332
1333 // Average now is 3 runs and (15 * 2 + 25)/ 3 = 18.33 = 18
1334 run2.Save();
1335 AssertStats(path, 3, 18);
1336
1337 Progress run3 = GetInstance(-42, 1.2, path);
1338 EXPECT_EQ(0, run3.Get());
1339 EXPECT_EQ(18, run3.GetInitialMax());
1340 EXPECT_EQ(18, run3.GetMax());
1341
1342 // Make sure average decreases as well
1343 max_increased = run3.Inc(5);
1344 EXPECT_EQ(5, run3.Get());
1345 EXPECT_EQ(18, run3.GetMax());
1346 EXPECT_FALSE(max_increased);
1347
1348 // Average now is 4 runs and (18 * 3 + 5)/ 4 = 14.75 = 14
1349 run3.Save();
1350 AssertStats(path, 4, 14);
1351}
1352
1353// Tests what happens when the persistent settings contains the average duration of 2 runs.
1354// Data on file is 2 runs and 15 average.
1355TEST_F(ProgressTest, ThirdTime) {
1356 std::string path = CopyTextFileFixture("stats-two-runs.txt");
1357 AssertStats(path, 2, 15); // Sanity check
1358
1359 Progress run1 = GetInstance(-42, 1.2, path);
1360 EXPECT_EQ(0, run1.Get());
1361 EXPECT_EQ(15, run1.GetInitialMax());
1362 EXPECT_EQ(15, run1.GetMax());
1363
1364 bool max_increased = run1.Inc(20);
1365 EXPECT_EQ(20, run1.Get());
1366 EXPECT_EQ(24, run1.GetMax());
1367 EXPECT_TRUE(max_increased);
1368
1369 // Average now is 3 runs and (15 * 2 + 20)/ 3 = 16.66 = 16
1370 run1.Save();
1371 AssertStats(path, 3, 16);
1372}
1373
Felipe Leme46b85da2016-11-21 17:40:45 -08001374class DumpstateUtilTest : public DumpstateBaseTest {
1375 public:
1376 void SetUp() {
1377 DumpstateBaseTest::SetUp();
1378 SetDryRun(false);
1379 }
1380
Felipe Leme46b85da2016-11-21 17:40:45 -08001381 void CaptureFdOut() {
Felipe Lemef0292972016-11-22 13:57:05 -08001382 ReadFileToString(path_, &out);
Felipe Leme46b85da2016-11-21 17:40:45 -08001383 }
1384
1385 void CreateFd(const std::string& name) {
1386 path_ = kTestDataPath + name;
1387 MYLOGD("Creating fd for file %s\n", path_.c_str());
1388
1389 fd = TEMP_FAILURE_RETRY(open(path_.c_str(),
1390 O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW,
1391 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH));
1392 ASSERT_GE(fd, 0) << "could not create FD for path " << path_;
1393 }
1394
1395 // Runs a command into the `fd` and capture `stderr`.
Felipe Lemef0292972016-11-22 13:57:05 -08001396 int RunCommand(const std::string& title, const std::vector<std::string>& full_command,
Felipe Leme46b85da2016-11-21 17:40:45 -08001397 const CommandOptions& options = CommandOptions::DEFAULT) {
1398 CaptureStderr();
Felipe Lemef0292972016-11-22 13:57:05 -08001399 int status = RunCommandToFd(fd, title, full_command, options);
Felipe Leme46b85da2016-11-21 17:40:45 -08001400 close(fd);
1401
1402 CaptureFdOut();
1403 err = GetCapturedStderr();
1404 return status;
1405 }
1406
1407 // Dumps a file and into the `fd` and `stderr`.
Felipe Lemef0292972016-11-22 13:57:05 -08001408 int DumpFile(const std::string& title, const std::string& path) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001409 CaptureStderr();
Felipe Lemef0292972016-11-22 13:57:05 -08001410 int status = DumpFileToFd(fd, title, path);
Felipe Leme46b85da2016-11-21 17:40:45 -08001411 close(fd);
1412
1413 CaptureFdOut();
1414 err = GetCapturedStderr();
1415 return status;
1416 }
1417
Ecco Park61ffcf72016-10-27 15:46:26 -07001418 // Find out the pid of the process_name
1419 int FindPidOfProcess(const std::string& process_name) {
1420 CaptureStderr();
1421 int status = GetPidByName(process_name);
1422 err = GetCapturedStderr();
1423 return status;
1424 }
1425
Felipe Leme46b85da2016-11-21 17:40:45 -08001426 int fd;
1427
1428 // 'fd` output and `stderr` from the last command ran.
1429 std::string out, err;
1430
1431 private:
1432 std::string path_;
1433};
1434
1435TEST_F(DumpstateUtilTest, RunCommandNoArgs) {
Felipe Lemef0292972016-11-22 13:57:05 -08001436 CreateFd("RunCommandNoArgs.txt");
1437 EXPECT_EQ(-1, RunCommand("", {}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001438}
1439
Felipe Lemef0292972016-11-22 13:57:05 -08001440TEST_F(DumpstateUtilTest, RunCommandNoTitle) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001441 CreateFd("RunCommandWithNoArgs.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001442 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001443 EXPECT_THAT(out, StrEq("stdout\n"));
1444 EXPECT_THAT(err, StrEq("stderr\n"));
1445}
1446
Felipe Lemef0292972016-11-22 13:57:05 -08001447TEST_F(DumpstateUtilTest, RunCommandWithTitle) {
1448 CreateFd("RunCommandWithNoArgs.txt");
1449 EXPECT_EQ(0, RunCommand("I AM GROOT", {kSimpleCommand}));
1450 EXPECT_THAT(out, StrEq("------ I AM GROOT (" + kSimpleCommand + ") ------\nstdout\n"));
1451 EXPECT_THAT(err, StrEq("stderr\n"));
1452}
1453
Felipe Leme46b85da2016-11-21 17:40:45 -08001454TEST_F(DumpstateUtilTest, RunCommandWithOneArg) {
1455 CreateFd("RunCommandWithOneArg.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001456 EXPECT_EQ(0, RunCommand("", {kEchoCommand, "one"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001457 EXPECT_THAT(err, IsEmpty());
1458 EXPECT_THAT(out, StrEq("one\n"));
1459}
1460
1461TEST_F(DumpstateUtilTest, RunCommandWithMultipleArgs) {
1462 CreateFd("RunCommandWithMultipleArgs.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001463 EXPECT_EQ(0, RunCommand("", {kEchoCommand, "one", "is", "the", "loniest", "number"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001464 EXPECT_THAT(err, IsEmpty());
1465 EXPECT_THAT(out, StrEq("one is the loniest number\n"));
1466}
1467
1468TEST_F(DumpstateUtilTest, RunCommandWithLoggingMessage) {
1469 CreateFd("RunCommandWithLoggingMessage.txt");
1470 EXPECT_EQ(
Felipe Lemef0292972016-11-22 13:57:05 -08001471 0, RunCommand("", {kSimpleCommand},
Felipe Leme46b85da2016-11-21 17:40:45 -08001472 CommandOptions::WithTimeout(10).Log("COMMAND, Y U NO LOG FIRST?").Build()));
1473 EXPECT_THAT(out, StrEq("stdout\n"));
1474 EXPECT_THAT(err, StrEq("COMMAND, Y U NO LOG FIRST?stderr\n"));
1475}
1476
1477TEST_F(DumpstateUtilTest, RunCommandRedirectStderr) {
1478 CreateFd("RunCommandRedirectStderr.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001479 EXPECT_EQ(0, RunCommand("", {kSimpleCommand},
1480 CommandOptions::WithTimeout(10).RedirectStderr().Build()));
Felipe Leme46b85da2016-11-21 17:40:45 -08001481 EXPECT_THAT(out, IsEmpty());
1482 EXPECT_THAT(err, StrEq("stdout\nstderr\n"));
1483}
1484
1485TEST_F(DumpstateUtilTest, RunCommandDryRun) {
1486 CreateFd("RunCommandDryRun.txt");
1487 SetDryRun(true);
Felipe Lemef0292972016-11-22 13:57:05 -08001488 EXPECT_EQ(0, RunCommand("I AM GROOT", {kSimpleCommand}));
1489 EXPECT_THAT(out, StrEq(android::base::StringPrintf(
1490 "------ I AM GROOT (%s) ------\n\t(skipped on dry run)\n",
1491 kSimpleCommand.c_str())));
1492 EXPECT_THAT(err, IsEmpty());
1493}
1494
1495TEST_F(DumpstateUtilTest, RunCommandDryRunNoTitle) {
1496 CreateFd("RunCommandDryRun.txt");
1497 SetDryRun(true);
1498 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001499 EXPECT_THAT(
1500 out, StrEq(android::base::StringPrintf("%s: skipped on dry run\n", kSimpleCommand.c_str())));
1501 EXPECT_THAT(err, IsEmpty());
1502}
1503
1504TEST_F(DumpstateUtilTest, RunCommandDryRunAlways) {
1505 CreateFd("RunCommandDryRunAlways.txt");
1506 SetDryRun(true);
Felipe Lemef0292972016-11-22 13:57:05 -08001507 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(10).Always().Build()));
Felipe Leme46b85da2016-11-21 17:40:45 -08001508 EXPECT_THAT(out, StrEq("stdout\n"));
1509 EXPECT_THAT(err, StrEq("stderr\n"));
1510}
1511
1512TEST_F(DumpstateUtilTest, RunCommandNotFound) {
1513 CreateFd("RunCommandNotFound.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001514 EXPECT_NE(0, RunCommand("", {"/there/cannot/be/such/command"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001515 EXPECT_THAT(out, StartsWith("*** command '/there/cannot/be/such/command' failed: exit code"));
1516 EXPECT_THAT(err, StartsWith("execvp on command '/there/cannot/be/such/command' failed"));
1517}
1518
1519TEST_F(DumpstateUtilTest, RunCommandFails) {
1520 CreateFd("RunCommandFails.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001521 EXPECT_EQ(42, RunCommand("", {kSimpleCommand, "--exit", "42"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001522 EXPECT_THAT(out, StrEq("stdout\n*** command '" + kSimpleCommand +
1523 " --exit 42' failed: exit code 42\n"));
1524 EXPECT_THAT(err, StrEq("stderr\n*** command '" + kSimpleCommand +
1525 " --exit 42' failed: exit code 42\n"));
1526}
1527
1528TEST_F(DumpstateUtilTest, RunCommandCrashes) {
1529 CreateFd("RunCommandCrashes.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001530 EXPECT_NE(0, RunCommand("", {kSimpleCommand, "--crash"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001531 // We don't know the exit code, so check just the prefix.
1532 EXPECT_THAT(
1533 out, StartsWith("stdout\n*** command '" + kSimpleCommand + " --crash' failed: exit code"));
1534 EXPECT_THAT(
1535 err, StartsWith("stderr\n*** command '" + kSimpleCommand + " --crash' failed: exit code"));
1536}
1537
Vishnu Nair6921f802017-11-22 09:17:23 -08001538TEST_F(DumpstateUtilTest, RunCommandTimesoutWithSec) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001539 CreateFd("RunCommandTimesout.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001540 EXPECT_EQ(-1, RunCommand("", {kSimpleCommand, "--sleep", "2"},
1541 CommandOptions::WithTimeout(1).Build()));
Felipe Leme46b85da2016-11-21 17:40:45 -08001542 EXPECT_THAT(out, StartsWith("stdout line1\n*** command '" + kSimpleCommand +
1543 " --sleep 2' timed out after 1"));
1544 EXPECT_THAT(err, StartsWith("sleeping for 2s\n*** command '" + kSimpleCommand +
1545 " --sleep 2' timed out after 1"));
1546}
1547
Vishnu Nair6921f802017-11-22 09:17:23 -08001548TEST_F(DumpstateUtilTest, RunCommandTimesoutWithMsec) {
1549 CreateFd("RunCommandTimesout.txt");
1550 EXPECT_EQ(-1, RunCommand("", {kSimpleCommand, "--sleep", "2"},
1551 CommandOptions::WithTimeoutInMs(1000).Build()));
1552 EXPECT_THAT(out, StartsWith("stdout line1\n*** command '" + kSimpleCommand +
1553 " --sleep 2' timed out after 1"));
1554 EXPECT_THAT(err, StartsWith("sleeping for 2s\n*** command '" + kSimpleCommand +
1555 " --sleep 2' timed out after 1"));
1556}
1557
1558
Felipe Leme46b85da2016-11-21 17:40:45 -08001559TEST_F(DumpstateUtilTest, RunCommandIsKilled) {
1560 CreateFd("RunCommandIsKilled.txt");
1561 CaptureStderr();
1562
1563 std::thread t([=]() {
Felipe Lemef0292972016-11-22 13:57:05 -08001564 EXPECT_EQ(SIGTERM, RunCommandToFd(fd, "", {kSimpleCommand, "--pid", "--sleep", "20"},
Felipe Leme46b85da2016-11-21 17:40:45 -08001565 CommandOptions::WithTimeout(100).Always().Build()));
1566 });
1567
1568 // Capture pid and pre-sleep output.
1569 sleep(1); // Wait a little bit to make sure pid and 1st line were printed.
1570 std::string err = GetCapturedStderr();
1571 EXPECT_THAT(err, StrEq("sleeping for 20s\n"));
1572
1573 CaptureFdOut();
1574 std::vector<std::string> lines = android::base::Split(out, "\n");
1575 ASSERT_EQ(3, (int)lines.size()) << "Invalid lines before sleep: " << out;
1576
1577 int pid = atoi(lines[0].c_str());
1578 EXPECT_THAT(lines[1], StrEq("stdout line1"));
1579 EXPECT_THAT(lines[2], IsEmpty()); // \n
1580
1581 // Then kill the process.
1582 CaptureFdOut();
1583 CaptureStderr();
1584 ASSERT_EQ(0, kill(pid, SIGTERM)) << "failed to kill pid " << pid;
1585 t.join();
1586
1587 // Finally, check output after murder.
1588 CaptureFdOut();
1589 err = GetCapturedStderr();
1590
1591 // out starts with the pid, which is an unknown
1592 EXPECT_THAT(out, EndsWith("stdout line1\n*** command '" + kSimpleCommand +
1593 " --pid --sleep 20' failed: killed by signal 15\n"));
1594 EXPECT_THAT(err, StrEq("*** command '" + kSimpleCommand +
1595 " --pid --sleep 20' failed: killed by signal 15\n"));
1596}
1597
1598TEST_F(DumpstateUtilTest, RunCommandAsRootUserBuild) {
1599 if (!IsStandalone()) {
1600 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1601 // to Shell - need to refactor tests to avoid this problem)
1602 MYLOGE("Skipping DumpstateUtilTest.RunCommandAsRootUserBuild() on test suite\n")
1603 return;
1604 }
1605 CreateFd("RunCommandAsRootUserBuild.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001606 if (!PropertiesHelper::IsUserBuild()) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001607 // Emulates user build if necessarily.
1608 SetBuildType("user");
1609 }
1610
1611 DropRoot();
1612
Felipe Lemef0292972016-11-22 13:57:05 -08001613 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).AsRoot().Build()));
Felipe Leme46b85da2016-11-21 17:40:45 -08001614
1615 // We don't know the exact path of su, so we just check for the 'root ...' commands
1616 EXPECT_THAT(out, StartsWith("Skipping"));
1617 EXPECT_THAT(out, EndsWith("root " + kSimpleCommand + "' on user build.\n"));
1618 EXPECT_THAT(err, IsEmpty());
1619}
1620
1621TEST_F(DumpstateUtilTest, RunCommandAsRootNonUserBuild) {
1622 if (!IsStandalone()) {
1623 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1624 // to Shell - need to refactor tests to avoid this problem)
1625 MYLOGE("Skipping DumpstateUtilTest.RunCommandAsRootNonUserBuild() on test suite\n")
1626 return;
1627 }
1628 CreateFd("RunCommandAsRootNonUserBuild.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001629 if (PropertiesHelper::IsUserBuild()) {
Felipe Leme7447d7c2016-11-03 18:12:22 -07001630 ALOGI("Skipping RunCommandAsRootNonUserBuild on user builds\n");
1631 return;
1632 }
1633
1634 DropRoot();
1635
Felipe Lemef0292972016-11-22 13:57:05 -08001636 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
1637 CommandOptions::WithTimeout(1).AsRoot().Build()));
Felipe Leme7447d7c2016-11-03 18:12:22 -07001638
1639 EXPECT_THAT(out, StrEq("0\nstdout\n"));
1640 EXPECT_THAT(err, StrEq("stderr\n"));
1641}
Felipe Leme46b85da2016-11-21 17:40:45 -08001642
Yifan Hong48e83a12017-10-03 14:10:07 -07001643
1644TEST_F(DumpstateUtilTest, RunCommandAsRootIfAvailableOnUserBuild) {
1645 if (!IsStandalone()) {
1646 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1647 // to Shell - need to refactor tests to avoid this problem)
1648 MYLOGE("Skipping DumpstateUtilTest.RunCommandAsRootIfAvailableOnUserBuild() on test suite\n")
1649 return;
1650 }
1651 CreateFd("RunCommandAsRootIfAvailableOnUserBuild.txt");
1652 if (!PropertiesHelper::IsUserBuild()) {
1653 // Emulates user build if necessarily.
1654 SetBuildType("user");
1655 }
1656
1657 DropRoot();
1658
1659 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
1660 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
1661
1662 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
1663 EXPECT_THAT(err, StrEq("stderr\n"));
1664}
1665
1666TEST_F(DumpstateUtilTest, RunCommandAsRootIfAvailableOnDebugBuild) {
1667 if (!IsStandalone()) {
1668 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1669 // to Shell - need to refactor tests to avoid this problem)
1670 MYLOGE("Skipping DumpstateUtilTest.RunCommandAsRootIfAvailableOnDebugBuild() on test suite\n")
1671 return;
1672 }
1673 CreateFd("RunCommandAsRootIfAvailableOnDebugBuild.txt");
1674 if (PropertiesHelper::IsUserBuild()) {
1675 ALOGI("Skipping RunCommandAsRootNonUserBuild on user builds\n");
1676 return;
1677 }
1678
1679 DropRoot();
1680
1681 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
1682 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
1683
1684 EXPECT_THAT(out, StrEq("0\nstdout\n"));
1685 EXPECT_THAT(err, StrEq("stderr\n"));
1686}
1687
Felipe Leme46b85da2016-11-21 17:40:45 -08001688TEST_F(DumpstateUtilTest, RunCommandDropRoot) {
1689 if (!IsStandalone()) {
1690 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1691 // to Shell - need to refactor tests to avoid this problem)
1692 MYLOGE("Skipping DumpstateUtilTest.RunCommandDropRoot() on test suite\n")
1693 return;
1694 }
1695 CreateFd("RunCommandDropRoot.txt");
1696 // First check root case - only available when running with 'adb root'.
1697 uid_t uid = getuid();
1698 if (uid == 0) {
Felipe Lemef0292972016-11-22 13:57:05 -08001699 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001700 EXPECT_THAT(out, StrEq("0\nstdout\n"));
1701 EXPECT_THAT(err, StrEq("stderr\n"));
1702 return;
1703 }
1704 // Then run dropping root.
Felipe Lemef0292972016-11-22 13:57:05 -08001705 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
Felipe Leme46b85da2016-11-21 17:40:45 -08001706 CommandOptions::WithTimeout(1).DropRoot().Build()));
1707 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
1708 EXPECT_THAT(err, StrEq("drop_root_user(): already running as Shell\nstderr\n"));
1709}
1710
Felipe Lemef0292972016-11-22 13:57:05 -08001711TEST_F(DumpstateUtilTest, DumpFileNotFoundNoTitle) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001712 CreateFd("DumpFileNotFound.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001713 EXPECT_EQ(-1, DumpFile("", "/I/cant/believe/I/exist"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001714 EXPECT_THAT(out,
1715 StrEq("*** Error dumping /I/cant/believe/I/exist: No such file or directory\n"));
1716 EXPECT_THAT(err, IsEmpty());
1717}
1718
Felipe Lemef0292972016-11-22 13:57:05 -08001719TEST_F(DumpstateUtilTest, DumpFileNotFoundWithTitle) {
1720 CreateFd("DumpFileNotFound.txt");
1721 EXPECT_EQ(-1, DumpFile("Y U NO EXIST?", "/I/cant/believe/I/exist"));
1722 EXPECT_THAT(out, StrEq("*** Error dumping /I/cant/believe/I/exist (Y U NO EXIST?): No such "
1723 "file or directory\n"));
1724 EXPECT_THAT(err, IsEmpty());
1725}
1726
Felipe Leme46b85da2016-11-21 17:40:45 -08001727TEST_F(DumpstateUtilTest, DumpFileSingleLine) {
1728 CreateFd("DumpFileSingleLine.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001729 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001730 EXPECT_THAT(err, IsEmpty());
1731 EXPECT_THAT(out, StrEq("I AM LINE1\n")); // dumpstate adds missing newline
1732}
1733
1734TEST_F(DumpstateUtilTest, DumpFileSingleLineWithNewLine) {
1735 CreateFd("DumpFileSingleLineWithNewLine.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001736 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line-with-newline.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001737 EXPECT_THAT(err, IsEmpty());
1738 EXPECT_THAT(out, StrEq("I AM LINE1\n"));
1739}
1740
1741TEST_F(DumpstateUtilTest, DumpFileMultipleLines) {
1742 CreateFd("DumpFileMultipleLines.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001743 EXPECT_EQ(0, DumpFile("", kTestDataPath + "multiple-lines.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001744 EXPECT_THAT(err, IsEmpty());
1745 EXPECT_THAT(out, StrEq("I AM LINE1\nI AM LINE2\nI AM LINE3\n"));
1746}
1747
1748TEST_F(DumpstateUtilTest, DumpFileMultipleLinesWithNewLine) {
1749 CreateFd("DumpFileMultipleLinesWithNewLine.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001750 EXPECT_EQ(0, DumpFile("", kTestDataPath + "multiple-lines-with-newline.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001751 EXPECT_THAT(err, IsEmpty());
1752 EXPECT_THAT(out, StrEq("I AM LINE1\nI AM LINE2\nI AM LINE3\n"));
1753}
1754
Felipe Lemef0292972016-11-22 13:57:05 -08001755TEST_F(DumpstateUtilTest, DumpFileOnDryRunNoTitle) {
1756 CreateFd("DumpFileOnDryRun.txt");
1757 SetDryRun(true);
1758 std::string path = kTestDataPath + "single-line.txt";
1759 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
1760 EXPECT_THAT(err, IsEmpty());
1761 EXPECT_THAT(out, StrEq(path + ": skipped on dry run\n"));
1762}
1763
Felipe Leme46b85da2016-11-21 17:40:45 -08001764TEST_F(DumpstateUtilTest, DumpFileOnDryRun) {
1765 CreateFd("DumpFileOnDryRun.txt");
1766 SetDryRun(true);
1767 std::string path = kTestDataPath + "single-line.txt";
Felipe Lemef0292972016-11-22 13:57:05 -08001768 EXPECT_EQ(0, DumpFile("Might as well dump. Dump!", kTestDataPath + "single-line.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001769 EXPECT_THAT(err, IsEmpty());
Felipe Lemef0292972016-11-22 13:57:05 -08001770 EXPECT_THAT(
1771 out, StartsWith("------ Might as well dump. Dump! (" + kTestDataPath + "single-line.txt:"));
1772 EXPECT_THAT(out, EndsWith("skipped on dry run\n"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001773}
Ecco Park61ffcf72016-10-27 15:46:26 -07001774
1775TEST_F(DumpstateUtilTest, FindingPidWithExistingProcess) {
1776 // init process always has pid 1.
1777 EXPECT_EQ(1, FindPidOfProcess("init"));
1778 EXPECT_THAT(err, IsEmpty());
1779}
1780
1781TEST_F(DumpstateUtilTest, FindingPidWithNotExistingProcess) {
1782 // find the process with abnormal name.
1783 EXPECT_EQ(-1, FindPidOfProcess("abcdef12345-543"));
1784 EXPECT_THAT(err, StrEq("can't find the pid\n"));
1785}
Felipe Leme47e9be22016-12-21 15:37:07 -08001786
1787} // namespace dumpstate
1788} // namespace os
1789} // namespace android