Home | History | Annotate | Download | only in tests
      1 /*
      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 
     17 #define LOG_TAG "dumpstate"
     18 #include <cutils/log.h>
     19 
     20 #include "DumpstateInternal.h"
     21 #include "DumpstateService.h"
     22 #include "android/os/BnDumpstate.h"
     23 #include "dumpstate.h"
     24 
     25 #include <gmock/gmock.h>
     26 #include <gtest/gtest.h>
     27 
     28 #include <fcntl.h>
     29 #include <libgen.h>
     30 #include <signal.h>
     31 #include <sys/types.h>
     32 #include <unistd.h>
     33 #include <thread>
     34 
     35 #include <android-base/file.h>
     36 #include <android-base/properties.h>
     37 #include <android-base/stringprintf.h>
     38 #include <android-base/strings.h>
     39 #include <cutils/properties.h>
     40 
     41 namespace android {
     42 namespace os {
     43 namespace dumpstate {
     44 
     45 using ::testing::EndsWith;
     46 using ::testing::HasSubstr;
     47 using ::testing::IsNull;
     48 using ::testing::IsEmpty;
     49 using ::testing::NotNull;
     50 using ::testing::StrEq;
     51 using ::testing::StartsWith;
     52 using ::testing::Test;
     53 using ::testing::internal::CaptureStderr;
     54 using ::testing::internal::CaptureStdout;
     55 using ::testing::internal::GetCapturedStderr;
     56 using ::testing::internal::GetCapturedStdout;
     57 
     58 #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
     59 
     60 class DumpstateListenerMock : public IDumpstateListener {
     61   public:
     62     MOCK_METHOD1(onProgress, binder::Status(int32_t progress));
     63     MOCK_METHOD1(onError, binder::Status(int32_t error_code));
     64     MOCK_METHOD0(onFinished, binder::Status());
     65     MOCK_METHOD1(onProgressUpdated, binder::Status(int32_t progress));
     66     MOCK_METHOD1(onMaxProgressUpdated, binder::Status(int32_t max_progress));
     67     MOCK_METHOD4(onSectionComplete, binder::Status(const ::std::string& name, int32_t status,
     68                                                    int32_t size, int32_t durationMs));
     69 
     70   protected:
     71     MOCK_METHOD0(onAsBinder, IBinder*());
     72 };
     73 
     74 static int calls_;
     75 
     76 // Base class for all tests in this file
     77 class DumpstateBaseTest : public Test {
     78   public:
     79     virtual void SetUp() override {
     80         calls_++;
     81         SetDryRun(false);
     82     }
     83 
     84     void SetDryRun(bool dry_run) const {
     85         PropertiesHelper::dry_run_ = dry_run;
     86     }
     87 
     88     void SetBuildType(const std::string& build_type) const {
     89         PropertiesHelper::build_type_ = build_type;
     90     }
     91 
     92     void SetUnroot(bool unroot) const {
     93         PropertiesHelper::unroot_ = unroot;
     94     }
     95 
     96     bool IsStandalone() const {
     97         return calls_ == 1;
     98     }
     99 
    100     void DropRoot() const {
    101         DropRootUser();
    102         uid_t uid = getuid();
    103         ASSERT_EQ(2000, (int)uid);
    104     }
    105 
    106   protected:
    107     const std::string kTestPath = dirname(android::base::GetExecutablePath().c_str());
    108     const std::string kFixturesPath = kTestPath + "/../dumpstate_test_fixture/";
    109     const std::string kTestDataPath = kFixturesPath + "tests/testdata/";
    110     const std::string kSimpleCommand = kFixturesPath + "dumpstate_test_fixture";
    111     const std::string kEchoCommand = "/system/bin/echo";
    112 
    113     /*
    114      * Copies a text file fixture to a temporary file, returning it's path.
    115      *
    116      * Useful in cases where the test case changes the content of the tile.
    117      */
    118     std::string CopyTextFileFixture(const std::string& relative_name) {
    119         std::string from = kTestDataPath + relative_name;
    120         // Not using TemporaryFile because it's deleted at the end, and it's useful to keep it
    121         // around for poking when the test fails.
    122         std::string to = kTestDataPath + relative_name + ".tmp";
    123         ALOGD("CopyTextFileFixture: from %s to %s\n", from.c_str(), to.c_str());
    124         android::base::RemoveFileIfExists(to);
    125         CopyTextFile(from, to);
    126         return to.c_str();
    127     }
    128 
    129     // Need functions that returns void to use assertions -
    130     // https://github.com/google/googletest/blob/master/googletest/docs/AdvancedGuide.md#assertion-placement
    131     void ReadFileToString(const std::string& path, std::string* content) {
    132         ASSERT_TRUE(android::base::ReadFileToString(path, content))
    133             << "could not read contents from " << path;
    134     }
    135     void WriteStringToFile(const std::string& content, const std::string& path) {
    136         ASSERT_TRUE(android::base::WriteStringToFile(content, path))
    137             << "could not write contents to " << path;
    138     }
    139 
    140   private:
    141     void CopyTextFile(const std::string& from, const std::string& to) {
    142         std::string content;
    143         ReadFileToString(from, &content);
    144         WriteStringToFile(content, to);
    145     }
    146 };
    147 
    148 class DumpOptionsTest : public Test {
    149   public:
    150     virtual ~DumpOptionsTest() {
    151     }
    152     virtual void SetUp() {
    153         options_ = Dumpstate::DumpOptions();
    154     }
    155     void TearDown() {
    156         // Reset the property
    157         property_set("dumpstate.options", "");
    158     }
    159     Dumpstate::DumpOptions options_;
    160 };
    161 
    162 TEST_F(DumpOptionsTest, InitializeNone) {
    163     // clang-format off
    164     char* argv[] = {
    165         const_cast<char*>("dumpstate")
    166     };
    167     // clang-format on
    168 
    169     Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
    170 
    171     EXPECT_EQ(status, Dumpstate::RunStatus::OK);
    172 
    173     EXPECT_FALSE(options_.do_add_date);
    174     EXPECT_FALSE(options_.do_zip_file);
    175     EXPECT_FALSE(options_.use_socket);
    176     EXPECT_FALSE(options_.use_control_socket);
    177     EXPECT_FALSE(options_.show_header_only);
    178     EXPECT_TRUE(options_.do_vibrate);
    179     EXPECT_FALSE(options_.do_fb);
    180     EXPECT_FALSE(options_.do_progress_updates);
    181     EXPECT_FALSE(options_.is_remote_mode);
    182     EXPECT_FALSE(options_.do_broadcast);
    183 }
    184 
    185 TEST_F(DumpOptionsTest, InitializeAdbBugreport) {
    186     // clang-format off
    187     char* argv[] = {
    188         const_cast<char*>("dumpstatez"),
    189         const_cast<char*>("-S"),
    190         const_cast<char*>("-d"),
    191         const_cast<char*>("-z"),
    192     };
    193     // clang-format on
    194 
    195     Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
    196 
    197     EXPECT_EQ(status, Dumpstate::RunStatus::OK);
    198     EXPECT_TRUE(options_.do_add_date);
    199     EXPECT_TRUE(options_.do_zip_file);
    200     EXPECT_TRUE(options_.use_control_socket);
    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 
    212 TEST_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_FALSE(options_.do_add_date);
    228     EXPECT_FALSE(options_.do_zip_file);
    229     EXPECT_FALSE(options_.use_control_socket);
    230     EXPECT_FALSE(options_.show_header_only);
    231     EXPECT_FALSE(options_.do_fb);
    232     EXPECT_FALSE(options_.do_progress_updates);
    233     EXPECT_FALSE(options_.is_remote_mode);
    234     EXPECT_FALSE(options_.do_broadcast);
    235 }
    236 
    237 TEST_F(DumpOptionsTest, InitializeFullBugReport) {
    238     // clang-format off
    239     char* argv[] = {
    240         const_cast<char*>("bugreport"),
    241         const_cast<char*>("-d"),
    242         const_cast<char*>("-p"),
    243         const_cast<char*>("-B"),
    244         const_cast<char*>("-z"),
    245     };
    246     // clang-format on
    247     property_set("dumpstate.options", "bugreportfull");
    248 
    249     Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
    250 
    251     EXPECT_EQ(status, Dumpstate::RunStatus::OK);
    252     EXPECT_TRUE(options_.do_add_date);
    253     EXPECT_TRUE(options_.do_fb);
    254     EXPECT_TRUE(options_.do_zip_file);
    255     EXPECT_TRUE(options_.do_broadcast);
    256 
    257     // Other options retain default values
    258     EXPECT_TRUE(options_.do_vibrate);
    259     EXPECT_FALSE(options_.use_control_socket);
    260     EXPECT_FALSE(options_.show_header_only);
    261     EXPECT_FALSE(options_.do_progress_updates);
    262     EXPECT_FALSE(options_.is_remote_mode);
    263     EXPECT_FALSE(options_.use_socket);
    264     EXPECT_FALSE(options_.do_start_service);
    265 }
    266 
    267 TEST_F(DumpOptionsTest, InitializeInteractiveBugReport) {
    268     // clang-format off
    269     char* argv[] = {
    270         const_cast<char*>("bugreport"),
    271         const_cast<char*>("-d"),
    272         const_cast<char*>("-p"),
    273         const_cast<char*>("-B"),
    274         const_cast<char*>("-z"),
    275     };
    276     // clang-format on
    277 
    278     property_set("dumpstate.options", "bugreportplus");
    279 
    280     Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
    281 
    282     EXPECT_EQ(status, Dumpstate::RunStatus::OK);
    283     EXPECT_TRUE(options_.do_add_date);
    284     EXPECT_TRUE(options_.do_broadcast);
    285     EXPECT_TRUE(options_.do_zip_file);
    286     EXPECT_TRUE(options_.do_progress_updates);
    287     EXPECT_TRUE(options_.do_start_service);
    288     EXPECT_FALSE(options_.do_fb);
    289 
    290     // Other options retain default values
    291     EXPECT_TRUE(options_.do_vibrate);
    292     EXPECT_FALSE(options_.use_control_socket);
    293     EXPECT_FALSE(options_.show_header_only);
    294     EXPECT_FALSE(options_.is_remote_mode);
    295     EXPECT_FALSE(options_.use_socket);
    296 }
    297 
    298 TEST_F(DumpOptionsTest, InitializeRemoteBugReport) {
    299     // clang-format off
    300     char* argv[] = {
    301         const_cast<char*>("bugreport"),
    302         const_cast<char*>("-d"),
    303         const_cast<char*>("-p"),
    304         const_cast<char*>("-B"),
    305         const_cast<char*>("-z"),
    306     };
    307     // clang-format on
    308 
    309     property_set("dumpstate.options", "bugreportremote");
    310 
    311     Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
    312 
    313     EXPECT_EQ(status, Dumpstate::RunStatus::OK);
    314     EXPECT_TRUE(options_.do_add_date);
    315     EXPECT_TRUE(options_.do_broadcast);
    316     EXPECT_TRUE(options_.do_zip_file);
    317     EXPECT_TRUE(options_.is_remote_mode);
    318     EXPECT_FALSE(options_.do_vibrate);
    319     EXPECT_FALSE(options_.do_fb);
    320 
    321     // Other options retain default values
    322     EXPECT_FALSE(options_.use_control_socket);
    323     EXPECT_FALSE(options_.show_header_only);
    324     EXPECT_FALSE(options_.do_progress_updates);
    325     EXPECT_FALSE(options_.use_socket);
    326 }
    327 
    328 TEST_F(DumpOptionsTest, InitializeWearBugReport) {
    329     // clang-format off
    330     char* argv[] = {
    331         const_cast<char*>("bugreport"),
    332         const_cast<char*>("-d"),
    333         const_cast<char*>("-p"),
    334         const_cast<char*>("-B"),
    335         const_cast<char*>("-z"),
    336     };
    337     // clang-format on
    338 
    339     property_set("dumpstate.options", "bugreportwear");
    340 
    341     Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
    342 
    343     EXPECT_EQ(status, Dumpstate::RunStatus::OK);
    344     EXPECT_TRUE(options_.do_add_date);
    345     EXPECT_TRUE(options_.do_fb);
    346     EXPECT_TRUE(options_.do_broadcast);
    347     EXPECT_TRUE(options_.do_zip_file);
    348     EXPECT_TRUE(options_.do_progress_updates);
    349     EXPECT_TRUE(options_.do_start_service);
    350 
    351     // Other options retain default values
    352     EXPECT_TRUE(options_.do_vibrate);
    353     EXPECT_FALSE(options_.use_control_socket);
    354     EXPECT_FALSE(options_.show_header_only);
    355     EXPECT_FALSE(options_.is_remote_mode);
    356     EXPECT_FALSE(options_.use_socket);
    357 }
    358 
    359 TEST_F(DumpOptionsTest, InitializeTelephonyBugReport) {
    360     // clang-format off
    361     char* argv[] = {
    362         const_cast<char*>("bugreport"),
    363         const_cast<char*>("-d"),
    364         const_cast<char*>("-p"),
    365         const_cast<char*>("-B"),
    366         const_cast<char*>("-z"),
    367     };
    368     // clang-format on
    369 
    370     property_set("dumpstate.options", "bugreporttelephony");
    371 
    372     Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
    373 
    374     EXPECT_EQ(status, Dumpstate::RunStatus::OK);
    375     EXPECT_TRUE(options_.do_add_date);
    376     EXPECT_FALSE(options_.do_fb);
    377     EXPECT_TRUE(options_.do_broadcast);
    378     EXPECT_TRUE(options_.do_zip_file);
    379     EXPECT_TRUE(options_.telephony_only);
    380 
    381     // Other options retain default values
    382     EXPECT_TRUE(options_.do_vibrate);
    383     EXPECT_FALSE(options_.use_control_socket);
    384     EXPECT_FALSE(options_.show_header_only);
    385     EXPECT_FALSE(options_.do_progress_updates);
    386     EXPECT_FALSE(options_.is_remote_mode);
    387     EXPECT_FALSE(options_.use_socket);
    388 }
    389 
    390 TEST_F(DumpOptionsTest, InitializeWifiBugReport) {
    391     // clang-format off
    392     char* argv[] = {
    393         const_cast<char*>("bugreport"),
    394         const_cast<char*>("-d"),
    395         const_cast<char*>("-p"),
    396         const_cast<char*>("-B"),
    397         const_cast<char*>("-z"),
    398     };
    399     // clang-format on
    400 
    401     property_set("dumpstate.options", "bugreportwifi");
    402 
    403     Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
    404 
    405     EXPECT_EQ(status, Dumpstate::RunStatus::OK);
    406     EXPECT_TRUE(options_.do_add_date);
    407     EXPECT_FALSE(options_.do_fb);
    408     EXPECT_TRUE(options_.do_broadcast);
    409     EXPECT_TRUE(options_.do_zip_file);
    410     EXPECT_TRUE(options_.wifi_only);
    411 
    412     // Other options retain default values
    413     EXPECT_TRUE(options_.do_vibrate);
    414     EXPECT_FALSE(options_.use_control_socket);
    415     EXPECT_FALSE(options_.show_header_only);
    416     EXPECT_FALSE(options_.do_progress_updates);
    417     EXPECT_FALSE(options_.is_remote_mode);
    418     EXPECT_FALSE(options_.use_socket);
    419 }
    420 
    421 TEST_F(DumpOptionsTest, InitializeDefaultBugReport) {
    422     // default: commandline options are not overridden
    423     // clang-format off
    424     char* argv[] = {
    425         const_cast<char*>("bugreport"),
    426         const_cast<char*>("-d"),
    427         const_cast<char*>("-p"),
    428         const_cast<char*>("-B"),
    429         const_cast<char*>("-z"),
    430     };
    431     // clang-format on
    432 
    433     property_set("dumpstate.options", "");
    434 
    435     Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
    436 
    437     EXPECT_EQ(status, Dumpstate::RunStatus::OK);
    438     EXPECT_TRUE(options_.do_add_date);
    439     EXPECT_TRUE(options_.do_fb);
    440     EXPECT_TRUE(options_.do_zip_file);
    441     EXPECT_TRUE(options_.do_broadcast);
    442 
    443     // Other options retain default values
    444     EXPECT_TRUE(options_.do_vibrate);
    445     EXPECT_FALSE(options_.use_control_socket);
    446     EXPECT_FALSE(options_.show_header_only);
    447     EXPECT_FALSE(options_.do_progress_updates);
    448     EXPECT_FALSE(options_.is_remote_mode);
    449     EXPECT_FALSE(options_.use_socket);
    450     EXPECT_FALSE(options_.wifi_only);
    451 }
    452 
    453 TEST_F(DumpOptionsTest, InitializePartial1) {
    454     // clang-format off
    455     char* argv[] = {
    456         const_cast<char*>("dumpstate"),
    457         const_cast<char*>("-d"),
    458         const_cast<char*>("-z"),
    459         const_cast<char*>("-s"),
    460         const_cast<char*>("-S"),
    461 
    462     };
    463     // clang-format on
    464 
    465     Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
    466 
    467     EXPECT_EQ(status, Dumpstate::RunStatus::OK);
    468     EXPECT_TRUE(options_.do_add_date);
    469     EXPECT_TRUE(options_.do_zip_file);
    470     // TODO: Maybe we should trim the filename
    471     EXPECT_TRUE(options_.use_socket);
    472     EXPECT_TRUE(options_.use_control_socket);
    473 
    474     // Other options retain default values
    475     EXPECT_FALSE(options_.show_header_only);
    476     EXPECT_TRUE(options_.do_vibrate);
    477     EXPECT_FALSE(options_.do_fb);
    478     EXPECT_FALSE(options_.do_progress_updates);
    479     EXPECT_FALSE(options_.is_remote_mode);
    480     EXPECT_FALSE(options_.do_broadcast);
    481 }
    482 
    483 TEST_F(DumpOptionsTest, InitializePartial2) {
    484     // clang-format off
    485     char* argv[] = {
    486         const_cast<char*>("dumpstate"),
    487         const_cast<char*>("-v"),
    488         const_cast<char*>("-q"),
    489         const_cast<char*>("-p"),
    490         const_cast<char*>("-P"),
    491         const_cast<char*>("-R"),
    492         const_cast<char*>("-B"),
    493     };
    494     // clang-format on
    495 
    496     Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
    497 
    498     EXPECT_EQ(status, Dumpstate::RunStatus::OK);
    499     EXPECT_TRUE(options_.show_header_only);
    500     EXPECT_FALSE(options_.do_vibrate);
    501     EXPECT_TRUE(options_.do_fb);
    502     EXPECT_TRUE(options_.do_progress_updates);
    503     EXPECT_TRUE(options_.is_remote_mode);
    504     EXPECT_TRUE(options_.do_broadcast);
    505 
    506     // Other options retain default values
    507     EXPECT_FALSE(options_.do_add_date);
    508     EXPECT_FALSE(options_.do_zip_file);
    509     EXPECT_FALSE(options_.use_socket);
    510     EXPECT_FALSE(options_.use_control_socket);
    511 }
    512 
    513 TEST_F(DumpOptionsTest, InitializeHelp) {
    514     // clang-format off
    515     char* argv[] = {
    516         const_cast<char*>("dumpstate"),
    517         const_cast<char*>("-h")
    518     };
    519     // clang-format on
    520 
    521     Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
    522 
    523     // -h is for help.
    524     EXPECT_EQ(status, Dumpstate::RunStatus::HELP);
    525 }
    526 
    527 TEST_F(DumpOptionsTest, InitializeUnknown) {
    528     // clang-format off
    529     char* argv[] = {
    530         const_cast<char*>("dumpstate"),
    531         const_cast<char*>("-u")  // unknown flag
    532     };
    533     // clang-format on
    534 
    535     Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
    536 
    537     // -u is unknown.
    538     EXPECT_EQ(status, Dumpstate::RunStatus::INVALID_INPUT);
    539 }
    540 
    541 TEST_F(DumpOptionsTest, ValidateOptionsNeedOutfile1) {
    542     options_.do_zip_file = true;
    543     // Writing to socket = !writing to file.
    544     options_.use_socket = true;
    545     EXPECT_FALSE(options_.ValidateOptions());
    546 
    547     options_.use_socket = false;
    548     EXPECT_TRUE(options_.ValidateOptions());
    549 }
    550 
    551 TEST_F(DumpOptionsTest, ValidateOptionsNeedOutfile2) {
    552     options_.do_broadcast = true;
    553     // Writing to socket = !writing to file.
    554     options_.use_socket = true;
    555     EXPECT_FALSE(options_.ValidateOptions());
    556 
    557     options_.use_socket = false;
    558     EXPECT_TRUE(options_.ValidateOptions());
    559 }
    560 
    561 TEST_F(DumpOptionsTest, ValidateOptionsNeedZipfile) {
    562     options_.use_control_socket = true;
    563     EXPECT_FALSE(options_.ValidateOptions());
    564 
    565     options_.do_zip_file = true;
    566     EXPECT_TRUE(options_.ValidateOptions());
    567 }
    568 
    569 TEST_F(DumpOptionsTest, ValidateOptionsUpdateProgressNeedsBroadcast) {
    570     options_.do_progress_updates = true;
    571     EXPECT_FALSE(options_.ValidateOptions());
    572 
    573     options_.do_broadcast = true;
    574     EXPECT_TRUE(options_.ValidateOptions());
    575 }
    576 
    577 TEST_F(DumpOptionsTest, ValidateOptionsRemoteMode) {
    578     options_.is_remote_mode = true;
    579     EXPECT_FALSE(options_.ValidateOptions());
    580 
    581     options_.do_broadcast = true;
    582     options_.do_zip_file = true;
    583     options_.do_add_date = true;
    584     EXPECT_TRUE(options_.ValidateOptions());
    585 }
    586 
    587 class DumpstateTest : public DumpstateBaseTest {
    588   public:
    589     void SetUp() {
    590         DumpstateBaseTest::SetUp();
    591         SetDryRun(false);
    592         SetBuildType(android::base::GetProperty("ro.build.type", "(unknown)"));
    593         ds.progress_.reset(new Progress());
    594         ds.update_progress_threshold_ = 0;
    595         ds.options_.reset(new Dumpstate::DumpOptions());
    596     }
    597 
    598     // Runs a command and capture `stdout` and `stderr`.
    599     int RunCommand(const std::string& title, const std::vector<std::string>& full_command,
    600                    const CommandOptions& options = CommandOptions::DEFAULT) {
    601         CaptureStdout();
    602         CaptureStderr();
    603         int status = ds.RunCommand(title, full_command, options);
    604         out = GetCapturedStdout();
    605         err = GetCapturedStderr();
    606         return status;
    607     }
    608 
    609     // Dumps a file and capture `stdout` and `stderr`.
    610     int DumpFile(const std::string& title, const std::string& path) {
    611         CaptureStdout();
    612         CaptureStderr();
    613         int status = ds.DumpFile(title, path);
    614         out = GetCapturedStdout();
    615         err = GetCapturedStderr();
    616         return status;
    617     }
    618 
    619     void SetProgress(long progress, long initial_max, long threshold = 0) {
    620         ds.options_->do_progress_updates = true;
    621         ds.update_progress_threshold_ = threshold;
    622         ds.last_updated_progress_ = 0;
    623         ds.progress_.reset(new Progress(initial_max, progress, 1.2));
    624     }
    625 
    626     std::string GetProgressMessage(const std::string& listener_name, int progress, int max,
    627                                    int old_max = 0, bool update_progress = true) {
    628         EXPECT_EQ(progress, ds.progress_->Get()) << "invalid progress";
    629         EXPECT_EQ(max, ds.progress_->GetMax()) << "invalid max";
    630 
    631         bool max_increased = old_max > 0;
    632 
    633         std::string message = "";
    634         if (max_increased) {
    635             message =
    636                 android::base::StringPrintf("Adjusting max progress from %d to %d\n", old_max, max);
    637         }
    638 
    639         if (update_progress) {
    640             message += android::base::StringPrintf("Setting progress (%s): %d/%d (%d%%)\n",
    641                                                    listener_name.c_str(), progress, max,
    642                                                    (100 * progress / max));
    643         }
    644 
    645         return message;
    646     }
    647 
    648     // `stdout` and `stderr` from the last command ran.
    649     std::string out, err;
    650 
    651     Dumpstate& ds = Dumpstate::GetInstance();
    652 };
    653 
    654 TEST_F(DumpstateTest, RunCommandNoArgs) {
    655     EXPECT_EQ(-1, RunCommand("", {}));
    656 }
    657 
    658 TEST_F(DumpstateTest, RunCommandNoTitle) {
    659     EXPECT_EQ(0, RunCommand("", {kSimpleCommand}));
    660     EXPECT_THAT(out, StrEq("stdout\n"));
    661     EXPECT_THAT(err, StrEq("stderr\n"));
    662 }
    663 
    664 TEST_F(DumpstateTest, RunCommandWithTitle) {
    665     EXPECT_EQ(0, RunCommand("I AM GROOT", {kSimpleCommand}));
    666     EXPECT_THAT(err, StrEq("stderr\n"));
    667     // We don't know the exact duration, so we check the prefix and suffix
    668     EXPECT_THAT(out,
    669                 StartsWith("------ I AM GROOT (" + kSimpleCommand + ") ------\nstdout\n"));
    670 }
    671 
    672 TEST_F(DumpstateTest, RunCommandWithLoggingMessage) {
    673     EXPECT_EQ(
    674         0, RunCommand("", {kSimpleCommand},
    675                       CommandOptions::WithTimeout(10).Log("COMMAND, Y U NO LOG FIRST?").Build()));
    676     EXPECT_THAT(out, StrEq("stdout\n"));
    677     EXPECT_THAT(err, StrEq("COMMAND, Y U NO LOG FIRST?stderr\n"));
    678 }
    679 
    680 TEST_F(DumpstateTest, RunCommandRedirectStderr) {
    681     EXPECT_EQ(0, RunCommand("", {kSimpleCommand},
    682                             CommandOptions::WithTimeout(10).RedirectStderr().Build()));
    683     EXPECT_THAT(out, IsEmpty());
    684     EXPECT_THAT(err, StrEq("stdout\nstderr\n"));
    685 }
    686 
    687 TEST_F(DumpstateTest, RunCommandWithOneArg) {
    688     EXPECT_EQ(0, RunCommand("", {kEchoCommand, "one"}));
    689     EXPECT_THAT(err, IsEmpty());
    690     EXPECT_THAT(out, StrEq("one\n"));
    691 }
    692 
    693 TEST_F(DumpstateTest, RunCommandWithMultipleArgs) {
    694     EXPECT_EQ(0, RunCommand("", {kEchoCommand, "one", "is", "the", "loniest", "number"}));
    695     EXPECT_THAT(err, IsEmpty());
    696     EXPECT_THAT(out, StrEq("one is the loniest number\n"));
    697 }
    698 
    699 TEST_F(DumpstateTest, RunCommandDryRun) {
    700     SetDryRun(true);
    701     EXPECT_EQ(0, RunCommand("I AM GROOT", {kSimpleCommand}));
    702     // We don't know the exact duration, so we check the prefix and suffix
    703     EXPECT_THAT(out, StartsWith("------ I AM GROOT (" + kSimpleCommand +
    704                                 ") ------\n\t(skipped on dry run)\n"));
    705     EXPECT_THAT(err, IsEmpty());
    706 }
    707 
    708 TEST_F(DumpstateTest, RunCommandDryRunNoTitle) {
    709     SetDryRun(true);
    710     EXPECT_EQ(0, RunCommand("", {kSimpleCommand}));
    711     EXPECT_THAT(out, IsEmpty());
    712     EXPECT_THAT(err, IsEmpty());
    713 }
    714 
    715 TEST_F(DumpstateTest, RunCommandDryRunAlways) {
    716     SetDryRun(true);
    717     EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(10).Always().Build()));
    718     EXPECT_THAT(out, StrEq("stdout\n"));
    719     EXPECT_THAT(err, StrEq("stderr\n"));
    720 }
    721 
    722 TEST_F(DumpstateTest, RunCommandNotFound) {
    723     EXPECT_NE(0, RunCommand("", {"/there/cannot/be/such/command"}));
    724     EXPECT_THAT(out, StartsWith("*** command '/there/cannot/be/such/command' failed: exit code"));
    725     EXPECT_THAT(err, StartsWith("execvp on command '/there/cannot/be/such/command' failed"));
    726 }
    727 
    728 TEST_F(DumpstateTest, RunCommandFails) {
    729     EXPECT_EQ(42, RunCommand("", {kSimpleCommand, "--exit", "42"}));
    730     EXPECT_THAT(out, StrEq("stdout\n*** command '" + kSimpleCommand +
    731                            " --exit 42' failed: exit code 42\n"));
    732     EXPECT_THAT(err, StrEq("stderr\n*** command '" + kSimpleCommand +
    733                            " --exit 42' failed: exit code 42\n"));
    734 }
    735 
    736 TEST_F(DumpstateTest, RunCommandCrashes) {
    737     EXPECT_NE(0, RunCommand("", {kSimpleCommand, "--crash"}));
    738     // We don't know the exit code, so check just the prefix.
    739     EXPECT_THAT(
    740         out, StartsWith("stdout\n*** command '" + kSimpleCommand + " --crash' failed: exit code"));
    741     EXPECT_THAT(
    742         err, StartsWith("stderr\n*** command '" + kSimpleCommand + " --crash' failed: exit code"));
    743 }
    744 
    745 TEST_F(DumpstateTest, RunCommandTimesout) {
    746     EXPECT_EQ(-1, RunCommand("", {kSimpleCommand, "--sleep", "2"},
    747                              CommandOptions::WithTimeout(1).Build()));
    748     EXPECT_THAT(out, StartsWith("stdout line1\n*** command '" + kSimpleCommand +
    749                                 " --sleep 2' timed out after 1"));
    750     EXPECT_THAT(err, StartsWith("sleeping for 2s\n*** command '" + kSimpleCommand +
    751                                 " --sleep 2' timed out after 1"));
    752 }
    753 
    754 TEST_F(DumpstateTest, RunCommandIsKilled) {
    755     CaptureStdout();
    756     CaptureStderr();
    757 
    758     std::thread t([=]() {
    759         EXPECT_EQ(SIGTERM, ds.RunCommand("", {kSimpleCommand, "--pid", "--sleep", "20"},
    760                                          CommandOptions::WithTimeout(100).Always().Build()));
    761     });
    762 
    763     // Capture pid and pre-sleep output.
    764     sleep(1);  // Wait a little bit to make sure pid and 1st line were printed.
    765     std::string err = GetCapturedStderr();
    766     EXPECT_THAT(err, StrEq("sleeping for 20s\n"));
    767 
    768     std::string out = GetCapturedStdout();
    769     std::vector<std::string> lines = android::base::Split(out, "\n");
    770     ASSERT_EQ(3, (int)lines.size()) << "Invalid lines before sleep: " << out;
    771 
    772     int pid = atoi(lines[0].c_str());
    773     EXPECT_THAT(lines[1], StrEq("stdout line1"));
    774     EXPECT_THAT(lines[2], IsEmpty());  // \n
    775 
    776     // Then kill the process.
    777     CaptureStdout();
    778     CaptureStderr();
    779     ASSERT_EQ(0, kill(pid, SIGTERM)) << "failed to kill pid " << pid;
    780     t.join();
    781 
    782     // Finally, check output after murder.
    783     out = GetCapturedStdout();
    784     err = GetCapturedStderr();
    785 
    786     EXPECT_THAT(out, StrEq("*** command '" + kSimpleCommand +
    787                            " --pid --sleep 20' failed: killed by signal 15\n"));
    788     EXPECT_THAT(err, StrEq("*** command '" + kSimpleCommand +
    789                            " --pid --sleep 20' failed: killed by signal 15\n"));
    790 }
    791 
    792 TEST_F(DumpstateTest, RunCommandProgress) {
    793     sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
    794     ds.listener_ = listener;
    795     ds.listener_name_ = "FoxMulder";
    796     SetProgress(0, 30);
    797 
    798     EXPECT_CALL(*listener, onProgressUpdated(20));
    799     EXPECT_CALL(*listener, onProgress(66));  // 20/30 %
    800     EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(20).Build()));
    801     std::string progress_message = GetProgressMessage(ds.listener_name_, 20, 30);
    802     EXPECT_THAT(out, StrEq("stdout\n"));
    803     EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
    804 
    805     EXPECT_CALL(*listener, onProgressUpdated(30));
    806     EXPECT_CALL(*listener, onProgress(100));  // 35/35 %
    807     EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(10).Build()));
    808     progress_message = GetProgressMessage(ds.listener_name_, 30, 30);
    809     EXPECT_THAT(out, StrEq("stdout\n"));
    810     EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
    811 
    812     // Run a command that will increase maximum timeout.
    813     EXPECT_CALL(*listener, onProgressUpdated(31));
    814     EXPECT_CALL(*listener, onMaxProgressUpdated(37));
    815     EXPECT_CALL(*listener, onProgress(83));  // 31/37 %
    816     EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).Build()));
    817     progress_message = GetProgressMessage(ds.listener_name_, 31, 37, 30);  // 20% increase
    818     EXPECT_THAT(out, StrEq("stdout\n"));
    819     EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
    820 
    821     // Make sure command ran while in dry_run is counted.
    822     SetDryRun(true);
    823     EXPECT_CALL(*listener, onProgressUpdated(35));
    824     EXPECT_CALL(*listener, onProgress(94));  // 35/37 %
    825     EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(4).Build()));
    826     progress_message = GetProgressMessage(ds.listener_name_, 35, 37);
    827     EXPECT_THAT(out, IsEmpty());
    828     EXPECT_THAT(err, StrEq(progress_message));
    829 
    830     ds.listener_.clear();
    831 }
    832 
    833 TEST_F(DumpstateTest, RunCommandProgressIgnoreThreshold) {
    834     sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
    835     ds.listener_ = listener;
    836     ds.listener_name_ = "FoxMulder";
    837     SetProgress(0, 8, 5);  // 8 max, 5 threshold
    838 
    839     // First update should always be sent.
    840     EXPECT_CALL(*listener, onProgressUpdated(1));
    841     EXPECT_CALL(*listener, onProgress(12));  // 1/12 %
    842     EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).Build()));
    843     std::string progress_message = GetProgressMessage(ds.listener_name_, 1, 8);
    844     EXPECT_THAT(out, StrEq("stdout\n"));
    845     EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
    846 
    847     // Fourth update should be ignored because it's between the threshold (5 -1 = 4 < 5).
    848     EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(4).Build()));
    849     EXPECT_THAT(out, StrEq("stdout\n"));
    850     EXPECT_THAT(err, StrEq("stderr\n"));
    851 
    852     // Third update should be sent because it reaches threshold (6 - 1 = 5).
    853     EXPECT_CALL(*listener, onProgressUpdated(6));
    854     EXPECT_CALL(*listener, onProgress(75));  // 6/8 %
    855     EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).Build()));
    856     progress_message = GetProgressMessage(ds.listener_name_, 6, 8);
    857     EXPECT_THAT(out, StrEq("stdout\n"));
    858     EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
    859 
    860     // Fourth update should be ignored because it's between the threshold (9 - 6 = 3 < 5).
    861     // But max update should be sent.
    862     EXPECT_CALL(*listener, onMaxProgressUpdated(10));  // 9 * 120% = 10.8 = 10
    863     EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(3).Build()));
    864     progress_message = GetProgressMessage(ds.listener_name_, 9, 10, 8, false);
    865     EXPECT_THAT(out, StrEq("stdout\n"));
    866     EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
    867 
    868     ds.listener_.clear();
    869 }
    870 
    871 TEST_F(DumpstateTest, RunCommandDropRoot) {
    872     if (!IsStandalone()) {
    873         // TODO: temporarily disabled because it might cause other tests to fail after dropping
    874         // to Shell - need to refactor tests to avoid this problem)
    875         MYLOGE("Skipping DumpstateTest.RunCommandDropRoot() on test suite\n")
    876         return;
    877     }
    878     // First check root case - only available when running with 'adb root'.
    879     uid_t uid = getuid();
    880     if (uid == 0) {
    881         EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"}));
    882         EXPECT_THAT(out, StrEq("0\nstdout\n"));
    883         EXPECT_THAT(err, StrEq("stderr\n"));
    884         return;
    885     }
    886     // Then run dropping root.
    887     EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
    888                             CommandOptions::WithTimeout(1).DropRoot().Build()));
    889     EXPECT_THAT(out, StrEq("2000\nstdout\n"));
    890     EXPECT_THAT(err, StrEq("drop_root_user(): already running as Shell\nstderr\n"));
    891 }
    892 
    893 TEST_F(DumpstateTest, RunCommandAsRootUserBuild) {
    894     if (!IsStandalone()) {
    895         // TODO: temporarily disabled because it might cause other tests to fail after dropping
    896         // to Shell - need to refactor tests to avoid this problem)
    897         MYLOGE("Skipping DumpstateTest.RunCommandAsRootUserBuild() on test suite\n")
    898         return;
    899     }
    900     if (!PropertiesHelper::IsUserBuild()) {
    901         // Emulates user build if necessarily.
    902         SetBuildType("user");
    903     }
    904 
    905     DropRoot();
    906 
    907     EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).AsRoot().Build()));
    908 
    909     // We don't know the exact path of su, so we just check for the 'root ...' commands
    910     EXPECT_THAT(out, StartsWith("Skipping"));
    911     EXPECT_THAT(out, EndsWith("root " + kSimpleCommand + "' on user build.\n"));
    912     EXPECT_THAT(err, IsEmpty());
    913 }
    914 
    915 TEST_F(DumpstateTest, RunCommandAsRootNonUserBuild) {
    916     if (!IsStandalone()) {
    917         // TODO: temporarily disabled because it might cause other tests to fail after dropping
    918         // to Shell - need to refactor tests to avoid this problem)
    919         MYLOGE("Skipping DumpstateTest.RunCommandAsRootNonUserBuild() on test suite\n")
    920         return;
    921     }
    922     if (PropertiesHelper::IsUserBuild()) {
    923         ALOGI("Skipping RunCommandAsRootNonUserBuild on user builds\n");
    924         return;
    925     }
    926 
    927     DropRoot();
    928 
    929     EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
    930                             CommandOptions::WithTimeout(1).AsRoot().Build()));
    931 
    932     EXPECT_THAT(out, StrEq("0\nstdout\n"));
    933     EXPECT_THAT(err, StrEq("stderr\n"));
    934 }
    935 
    936 TEST_F(DumpstateTest, RunCommandAsRootNonUserBuild_withUnroot) {
    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(
    941             "Skipping DumpstateTest.RunCommandAsRootNonUserBuild_withUnroot() "
    942             "on test suite\n")
    943         return;
    944     }
    945     if (PropertiesHelper::IsUserBuild()) {
    946         ALOGI("Skipping RunCommandAsRootNonUserBuild_withUnroot on user builds\n");
    947         return;
    948     }
    949 
    950     // Same test as above, but with unroot property set, which will override su availability.
    951     SetUnroot(true);
    952     DropRoot();
    953 
    954     EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
    955                             CommandOptions::WithTimeout(1).AsRoot().Build()));
    956 
    957     // AsRoot is ineffective.
    958     EXPECT_THAT(out, StrEq("2000\nstdout\n"));
    959     EXPECT_THAT(err, StrEq("drop_root_user(): already running as Shell\nstderr\n"));
    960 }
    961 
    962 TEST_F(DumpstateTest, RunCommandAsRootIfAvailableOnUserBuild) {
    963     if (!IsStandalone()) {
    964         // TODO: temporarily disabled because it might cause other tests to fail after dropping
    965         // to Shell - need to refactor tests to avoid this problem)
    966         MYLOGE("Skipping DumpstateTest.RunCommandAsRootIfAvailableOnUserBuild() on test suite\n")
    967         return;
    968     }
    969     if (!PropertiesHelper::IsUserBuild()) {
    970         // Emulates user build if necessarily.
    971         SetBuildType("user");
    972     }
    973 
    974     DropRoot();
    975 
    976     EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
    977                             CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
    978 
    979     EXPECT_THAT(out, StrEq("2000\nstdout\n"));
    980     EXPECT_THAT(err, StrEq("stderr\n"));
    981 }
    982 
    983 TEST_F(DumpstateTest, RunCommandAsRootIfAvailableOnDebugBuild) {
    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.RunCommandAsRootIfAvailableOnDebugBuild() on test suite\n")
    988         return;
    989     }
    990     if (PropertiesHelper::IsUserBuild()) {
    991         ALOGI("Skipping RunCommandAsRootNonUserBuild on user builds\n");
    992         return;
    993     }
    994 
    995     DropRoot();
    996 
    997     EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
    998                             CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
    999 
   1000     EXPECT_THAT(out, StrEq("0\nstdout\n"));
   1001     EXPECT_THAT(err, StrEq("stderr\n"));
   1002 }
   1003 
   1004 TEST_F(DumpstateTest, RunCommandAsRootIfAvailableOnDebugBuild_withUnroot) {
   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(
   1009             "Skipping DumpstateTest.RunCommandAsRootIfAvailableOnDebugBuild_withUnroot() "
   1010             "on test suite\n")
   1011         return;
   1012     }
   1013     if (PropertiesHelper::IsUserBuild()) {
   1014         ALOGI("Skipping RunCommandAsRootIfAvailableOnDebugBuild_withUnroot on user builds\n");
   1015         return;
   1016     }
   1017     // Same test as above, but with unroot property set, which will override su availability.
   1018     SetUnroot(true);
   1019 
   1020     DropRoot();
   1021 
   1022     EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
   1023                             CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
   1024 
   1025     // It's a userdebug build, so "su root" should be available, but unroot=true overrides it.
   1026     EXPECT_THAT(out, StrEq("2000\nstdout\n"));
   1027     EXPECT_THAT(err, StrEq("stderr\n"));
   1028 }
   1029 
   1030 TEST_F(DumpstateTest, DumpFileNotFoundNoTitle) {
   1031     EXPECT_EQ(-1, DumpFile("", "/I/cant/believe/I/exist"));
   1032     EXPECT_THAT(out,
   1033                 StrEq("*** Error dumping /I/cant/believe/I/exist: No such file or directory\n"));
   1034     EXPECT_THAT(err, IsEmpty());
   1035 }
   1036 
   1037 TEST_F(DumpstateTest, DumpFileNotFoundWithTitle) {
   1038     EXPECT_EQ(-1, DumpFile("Y U NO EXIST?", "/I/cant/believe/I/exist"));
   1039     EXPECT_THAT(err, IsEmpty());
   1040     // We don't know the exact duration, so we check the prefix and suffix
   1041     EXPECT_THAT(out, StartsWith("*** Error dumping /I/cant/believe/I/exist (Y U NO EXIST?): No "
   1042                                 "such file or directory\n"));
   1043 }
   1044 
   1045 TEST_F(DumpstateTest, DumpFileSingleLine) {
   1046     EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
   1047     EXPECT_THAT(err, IsEmpty());
   1048     EXPECT_THAT(out, StrEq("I AM LINE1\n"));  // dumpstate adds missing newline
   1049 }
   1050 
   1051 TEST_F(DumpstateTest, DumpFileSingleLineWithNewLine) {
   1052     EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line-with-newline.txt"));
   1053     EXPECT_THAT(err, IsEmpty());
   1054     EXPECT_THAT(out, StrEq("I AM LINE1\n"));
   1055 }
   1056 
   1057 TEST_F(DumpstateTest, DumpFileMultipleLines) {
   1058     EXPECT_EQ(0, DumpFile("", kTestDataPath + "multiple-lines.txt"));
   1059     EXPECT_THAT(err, IsEmpty());
   1060     EXPECT_THAT(out, StrEq("I AM LINE1\nI AM LINE2\nI AM LINE3\n"));
   1061 }
   1062 
   1063 TEST_F(DumpstateTest, DumpFileMultipleLinesWithNewLine) {
   1064     EXPECT_EQ(0, DumpFile("", kTestDataPath + "multiple-lines-with-newline.txt"));
   1065     EXPECT_THAT(err, IsEmpty());
   1066     EXPECT_THAT(out, StrEq("I AM LINE1\nI AM LINE2\nI AM LINE3\n"));
   1067 }
   1068 
   1069 TEST_F(DumpstateTest, DumpFileOnDryRunNoTitle) {
   1070     SetDryRun(true);
   1071     EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
   1072     EXPECT_THAT(err, IsEmpty());
   1073     EXPECT_THAT(out, IsEmpty());
   1074 }
   1075 
   1076 TEST_F(DumpstateTest, DumpFileOnDryRun) {
   1077     SetDryRun(true);
   1078     EXPECT_EQ(0, DumpFile("Might as well dump. Dump!", kTestDataPath + "single-line.txt"));
   1079     EXPECT_THAT(err, IsEmpty());
   1080     EXPECT_THAT(
   1081         out, StartsWith("------ Might as well dump. Dump! (" + kTestDataPath + "single-line.txt:"));
   1082     EXPECT_THAT(out, HasSubstr("\n\t(skipped on dry run)\n"));
   1083 }
   1084 
   1085 TEST_F(DumpstateTest, DumpFileUpdateProgress) {
   1086     sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
   1087     ds.listener_ = listener;
   1088     ds.listener_name_ = "FoxMulder";
   1089     SetProgress(0, 30);
   1090 
   1091     EXPECT_CALL(*listener, onProgressUpdated(5));
   1092     EXPECT_CALL(*listener, onProgress(16));  // 5/30 %
   1093     EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
   1094 
   1095     std::string progress_message =
   1096         GetProgressMessage(ds.listener_name_, 5, 30);  // TODO: unhardcode WEIGHT_FILE (5)?
   1097     EXPECT_THAT(err, StrEq(progress_message));
   1098     EXPECT_THAT(out, StrEq("I AM LINE1\n"));  // dumpstate adds missing newline
   1099 
   1100     ds.listener_.clear();
   1101 }
   1102 
   1103 class DumpstateServiceTest : public DumpstateBaseTest {
   1104   public:
   1105     DumpstateService dss;
   1106 };
   1107 
   1108 TEST_F(DumpstateServiceTest, SetListenerNoName) {
   1109     sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
   1110     sp<IDumpstateToken> token;
   1111     EXPECT_TRUE(dss.setListener("", listener, /* getSectionDetails = */ false, &token).isOk());
   1112     ASSERT_THAT(token, IsNull());
   1113 }
   1114 
   1115 TEST_F(DumpstateServiceTest, SetListenerNoPointer) {
   1116     sp<IDumpstateToken> token;
   1117     EXPECT_TRUE(
   1118         dss.setListener("whatever", nullptr, /* getSectionDetails = */ false, &token).isOk());
   1119     ASSERT_THAT(token, IsNull());
   1120 }
   1121 
   1122 TEST_F(DumpstateServiceTest, SetListenerTwice) {
   1123     sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
   1124     sp<IDumpstateToken> token;
   1125     EXPECT_TRUE(
   1126         dss.setListener("whatever", listener, /* getSectionDetails = */ false, &token).isOk());
   1127     ASSERT_THAT(token, NotNull());
   1128     EXPECT_THAT(Dumpstate::GetInstance().listener_name_, StrEq("whatever"));
   1129     EXPECT_FALSE(Dumpstate::GetInstance().report_section_);
   1130 
   1131     token.clear();
   1132     EXPECT_TRUE(
   1133         dss.setListener("whatsoever", listener, /* getSectionDetails = */ false, &token).isOk());
   1134     ASSERT_THAT(token, IsNull());
   1135     EXPECT_THAT(Dumpstate::GetInstance().listener_name_, StrEq("whatever"));
   1136     EXPECT_FALSE(Dumpstate::GetInstance().report_section_);
   1137 }
   1138 
   1139 TEST_F(DumpstateServiceTest, SetListenerWithSectionDetails) {
   1140     sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
   1141     sp<IDumpstateToken> token;
   1142     Dumpstate::GetInstance().listener_ = nullptr;
   1143     EXPECT_TRUE(
   1144         dss.setListener("whatever", listener, /* getSectionDetails = */ true, &token).isOk());
   1145     ASSERT_THAT(token, NotNull());
   1146     EXPECT_THAT(Dumpstate::GetInstance().listener_name_, StrEq("whatever"));
   1147     EXPECT_TRUE(Dumpstate::GetInstance().report_section_);
   1148 }
   1149 
   1150 class ProgressTest : public DumpstateBaseTest {
   1151   public:
   1152     Progress GetInstance(int32_t max, double growth_factor, const std::string& path = "") {
   1153         return Progress(max, growth_factor, path);
   1154     }
   1155 
   1156     void AssertStats(const std::string& path, int32_t expected_runs, int32_t expected_average) {
   1157         std::string expected_content =
   1158             android::base::StringPrintf("%d %d\n", expected_runs, expected_average);
   1159         std::string actual_content;
   1160         ReadFileToString(path, &actual_content);
   1161         ASSERT_THAT(actual_content, StrEq(expected_content)) << "invalid stats on " << path;
   1162     }
   1163 };
   1164 
   1165 TEST_F(ProgressTest, SimpleTest) {
   1166     Progress progress;
   1167     EXPECT_EQ(0, progress.Get());
   1168     EXPECT_EQ(Progress::kDefaultMax, progress.GetInitialMax());
   1169     EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
   1170 
   1171     bool max_increased = progress.Inc(1);
   1172     EXPECT_EQ(1, progress.Get());
   1173     EXPECT_EQ(Progress::kDefaultMax, progress.GetInitialMax());
   1174     EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
   1175     EXPECT_FALSE(max_increased);
   1176 
   1177     // Ignore negative increase.
   1178     max_increased = progress.Inc(-1);
   1179     EXPECT_EQ(1, progress.Get());
   1180     EXPECT_EQ(Progress::kDefaultMax, progress.GetInitialMax());
   1181     EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
   1182     EXPECT_FALSE(max_increased);
   1183 }
   1184 
   1185 TEST_F(ProgressTest, MaxGrowsInsideNewRange) {
   1186     Progress progress = GetInstance(10, 1.2);  // 20% growth factor
   1187     EXPECT_EQ(0, progress.Get());
   1188     EXPECT_EQ(10, progress.GetInitialMax());
   1189     EXPECT_EQ(10, progress.GetMax());
   1190 
   1191     // No increase
   1192     bool max_increased = progress.Inc(10);
   1193     EXPECT_EQ(10, progress.Get());
   1194     EXPECT_EQ(10, progress.GetMax());
   1195     EXPECT_FALSE(max_increased);
   1196 
   1197     // Increase, with new value < max*20%
   1198     max_increased = progress.Inc(1);
   1199     EXPECT_EQ(11, progress.Get());
   1200     EXPECT_EQ(13, progress.GetMax());  // 11 average * 20% growth = 13.2 = 13
   1201     EXPECT_TRUE(max_increased);
   1202 }
   1203 
   1204 TEST_F(ProgressTest, MaxGrowsOutsideNewRange) {
   1205     Progress progress = GetInstance(10, 1.2);  // 20% growth factor
   1206     EXPECT_EQ(0, progress.Get());
   1207     EXPECT_EQ(10, progress.GetInitialMax());
   1208     EXPECT_EQ(10, progress.GetMax());
   1209 
   1210     // No increase
   1211     bool max_increased = progress.Inc(10);
   1212     EXPECT_EQ(10, progress.Get());
   1213     EXPECT_EQ(10, progress.GetMax());
   1214     EXPECT_FALSE(max_increased);
   1215 
   1216     // Increase, with new value > max*20%
   1217     max_increased = progress.Inc(5);
   1218     EXPECT_EQ(15, progress.Get());
   1219     EXPECT_EQ(18, progress.GetMax());  // 15 average * 20% growth = 18
   1220     EXPECT_TRUE(max_increased);
   1221 }
   1222 
   1223 TEST_F(ProgressTest, InvalidPath) {
   1224     Progress progress("/devil/null");
   1225     EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
   1226 }
   1227 
   1228 TEST_F(ProgressTest, EmptyFile) {
   1229     Progress progress(CopyTextFileFixture("empty-file.txt"));
   1230     EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
   1231 }
   1232 
   1233 TEST_F(ProgressTest, InvalidLine1stEntryNAN) {
   1234     Progress progress(CopyTextFileFixture("stats-invalid-1st-NAN.txt"));
   1235     EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
   1236 }
   1237 
   1238 TEST_F(ProgressTest, InvalidLine2ndEntryNAN) {
   1239     Progress progress(CopyTextFileFixture("stats-invalid-2nd-NAN.txt"));
   1240     EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
   1241 }
   1242 
   1243 TEST_F(ProgressTest, InvalidLineBothNAN) {
   1244     Progress progress(CopyTextFileFixture("stats-invalid-both-NAN.txt"));
   1245     EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
   1246 }
   1247 
   1248 TEST_F(ProgressTest, InvalidLine1stEntryNegative) {
   1249     Progress progress(CopyTextFileFixture("stats-invalid-1st-negative.txt"));
   1250     EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
   1251 }
   1252 
   1253 TEST_F(ProgressTest, InvalidLine2ndEntryNegative) {
   1254     Progress progress(CopyTextFileFixture("stats-invalid-2nd-negative.txt"));
   1255     EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
   1256 }
   1257 
   1258 TEST_F(ProgressTest, InvalidLine1stEntryTooBig) {
   1259     Progress progress(CopyTextFileFixture("stats-invalid-1st-too-big.txt"));
   1260     EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
   1261 }
   1262 
   1263 TEST_F(ProgressTest, InvalidLine2ndEntryTooBig) {
   1264     Progress progress(CopyTextFileFixture("stats-invalid-2nd-too-big.txt"));
   1265     EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
   1266 }
   1267 
   1268 // Tests stats are properly saved when the file does not exists.
   1269 TEST_F(ProgressTest, FirstTime) {
   1270     if (!IsStandalone()) {
   1271         // TODO: temporarily disabled because it's failing when running as suite
   1272         MYLOGE("Skipping ProgressTest.FirstTime() on test suite\n")
   1273         return;
   1274     }
   1275 
   1276     std::string path = kTestDataPath + "FirstTime.txt";
   1277     android::base::RemoveFileIfExists(path);
   1278 
   1279     Progress run1(path);
   1280     EXPECT_EQ(0, run1.Get());
   1281     EXPECT_EQ(Progress::kDefaultMax, run1.GetInitialMax());
   1282     EXPECT_EQ(Progress::kDefaultMax, run1.GetMax());
   1283 
   1284     bool max_increased = run1.Inc(20);
   1285     EXPECT_EQ(20, run1.Get());
   1286     EXPECT_EQ(Progress::kDefaultMax, run1.GetMax());
   1287     EXPECT_FALSE(max_increased);
   1288 
   1289     run1.Save();
   1290     AssertStats(path, 1, 20);
   1291 }
   1292 
   1293 // Tests what happens when the persistent settings contains the average duration of 1 run.
   1294 // Data on file is 1 run and 109 average.
   1295 TEST_F(ProgressTest, SecondTime) {
   1296     std::string path = CopyTextFileFixture("stats-one-run-no-newline.txt");
   1297 
   1298     Progress run1 = GetInstance(-42, 1.2, path);
   1299     EXPECT_EQ(0, run1.Get());
   1300     EXPECT_EQ(10, run1.GetInitialMax());
   1301     EXPECT_EQ(10, run1.GetMax());
   1302 
   1303     bool max_increased = run1.Inc(20);
   1304     EXPECT_EQ(20, run1.Get());
   1305     EXPECT_EQ(24, run1.GetMax());
   1306     EXPECT_TRUE(max_increased);
   1307 
   1308     // Average now is 2 runs and (10 + 20)/ 2 = 15
   1309     run1.Save();
   1310     AssertStats(path, 2, 15);
   1311 
   1312     Progress run2 = GetInstance(-42, 1.2, path);
   1313     EXPECT_EQ(0, run2.Get());
   1314     EXPECT_EQ(15, run2.GetInitialMax());
   1315     EXPECT_EQ(15, run2.GetMax());
   1316 
   1317     max_increased = run2.Inc(25);
   1318     EXPECT_EQ(25, run2.Get());
   1319     EXPECT_EQ(30, run2.GetMax());
   1320     EXPECT_TRUE(max_increased);
   1321 
   1322     // Average now is 3 runs and (15 * 2 + 25)/ 3 = 18.33 = 18
   1323     run2.Save();
   1324     AssertStats(path, 3, 18);
   1325 
   1326     Progress run3 = GetInstance(-42, 1.2, path);
   1327     EXPECT_EQ(0, run3.Get());
   1328     EXPECT_EQ(18, run3.GetInitialMax());
   1329     EXPECT_EQ(18, run3.GetMax());
   1330 
   1331     // Make sure average decreases as well
   1332     max_increased = run3.Inc(5);
   1333     EXPECT_EQ(5, run3.Get());
   1334     EXPECT_EQ(18, run3.GetMax());
   1335     EXPECT_FALSE(max_increased);
   1336 
   1337     // Average now is 4 runs and (18 * 3 + 5)/ 4 = 14.75 = 14
   1338     run3.Save();
   1339     AssertStats(path, 4, 14);
   1340 }
   1341 
   1342 // Tests what happens when the persistent settings contains the average duration of 2 runs.
   1343 // Data on file is 2 runs and 15 average.
   1344 TEST_F(ProgressTest, ThirdTime) {
   1345     std::string path = CopyTextFileFixture("stats-two-runs.txt");
   1346     AssertStats(path, 2, 15);  // Sanity check
   1347 
   1348     Progress run1 = GetInstance(-42, 1.2, path);
   1349     EXPECT_EQ(0, run1.Get());
   1350     EXPECT_EQ(15, run1.GetInitialMax());
   1351     EXPECT_EQ(15, run1.GetMax());
   1352 
   1353     bool max_increased = run1.Inc(20);
   1354     EXPECT_EQ(20, run1.Get());
   1355     EXPECT_EQ(24, run1.GetMax());
   1356     EXPECT_TRUE(max_increased);
   1357 
   1358     // Average now is 3 runs and (15 * 2 + 20)/ 3 = 16.66 = 16
   1359     run1.Save();
   1360     AssertStats(path, 3, 16);
   1361 }
   1362 
   1363 class DumpstateUtilTest : public DumpstateBaseTest {
   1364   public:
   1365     void SetUp() {
   1366         DumpstateBaseTest::SetUp();
   1367         SetDryRun(false);
   1368     }
   1369 
   1370     void CaptureFdOut() {
   1371         ReadFileToString(path_, &out);
   1372     }
   1373 
   1374     void CreateFd(const std::string& name) {
   1375         path_ = kTestDataPath + name;
   1376         MYLOGD("Creating fd for file %s\n", path_.c_str());
   1377 
   1378         fd = TEMP_FAILURE_RETRY(open(path_.c_str(),
   1379                                      O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW,
   1380                                      S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH));
   1381         ASSERT_GE(fd, 0) << "could not create FD for path " << path_;
   1382     }
   1383 
   1384     // Runs a command into the `fd` and capture `stderr`.
   1385     int RunCommand(const std::string& title, const std::vector<std::string>& full_command,
   1386                    const CommandOptions& options = CommandOptions::DEFAULT) {
   1387         CaptureStderr();
   1388         int status = RunCommandToFd(fd, title, full_command, options);
   1389         close(fd);
   1390 
   1391         CaptureFdOut();
   1392         err = GetCapturedStderr();
   1393         return status;
   1394     }
   1395 
   1396     // Dumps a file and into the `fd` and `stderr`.
   1397     int DumpFile(const std::string& title, const std::string& path) {
   1398         CaptureStderr();
   1399         int status = DumpFileToFd(fd, title, path);
   1400         close(fd);
   1401 
   1402         CaptureFdOut();
   1403         err = GetCapturedStderr();
   1404         return status;
   1405     }
   1406 
   1407     // Find out the pid of the process_name
   1408     int FindPidOfProcess(const std::string& process_name) {
   1409         CaptureStderr();
   1410         int status = GetPidByName(process_name);
   1411         err = GetCapturedStderr();
   1412         return status;
   1413     }
   1414 
   1415     int fd;
   1416 
   1417     // 'fd` output and `stderr` from the last command ran.
   1418     std::string out, err;
   1419 
   1420   private:
   1421     std::string path_;
   1422 };
   1423 
   1424 TEST_F(DumpstateUtilTest, RunCommandNoArgs) {
   1425     CreateFd("RunCommandNoArgs.txt");
   1426     EXPECT_EQ(-1, RunCommand("", {}));
   1427 }
   1428 
   1429 TEST_F(DumpstateUtilTest, RunCommandNoTitle) {
   1430     CreateFd("RunCommandWithNoArgs.txt");
   1431     EXPECT_EQ(0, RunCommand("", {kSimpleCommand}));
   1432     EXPECT_THAT(out, StrEq("stdout\n"));
   1433     EXPECT_THAT(err, StrEq("stderr\n"));
   1434 }
   1435 
   1436 TEST_F(DumpstateUtilTest, RunCommandWithTitle) {
   1437     CreateFd("RunCommandWithNoArgs.txt");
   1438     EXPECT_EQ(0, RunCommand("I AM GROOT", {kSimpleCommand}));
   1439     EXPECT_THAT(out, StrEq("------ I AM GROOT (" + kSimpleCommand + ") ------\nstdout\n"));
   1440     EXPECT_THAT(err, StrEq("stderr\n"));
   1441 }
   1442 
   1443 TEST_F(DumpstateUtilTest, RunCommandWithOneArg) {
   1444     CreateFd("RunCommandWithOneArg.txt");
   1445     EXPECT_EQ(0, RunCommand("", {kEchoCommand, "one"}));
   1446     EXPECT_THAT(err, IsEmpty());
   1447     EXPECT_THAT(out, StrEq("one\n"));
   1448 }
   1449 
   1450 TEST_F(DumpstateUtilTest, RunCommandWithMultipleArgs) {
   1451     CreateFd("RunCommandWithMultipleArgs.txt");
   1452     EXPECT_EQ(0, RunCommand("", {kEchoCommand, "one", "is", "the", "loniest", "number"}));
   1453     EXPECT_THAT(err, IsEmpty());
   1454     EXPECT_THAT(out, StrEq("one is the loniest number\n"));
   1455 }
   1456 
   1457 TEST_F(DumpstateUtilTest, RunCommandWithLoggingMessage) {
   1458     CreateFd("RunCommandWithLoggingMessage.txt");
   1459     EXPECT_EQ(
   1460         0, RunCommand("", {kSimpleCommand},
   1461                       CommandOptions::WithTimeout(10).Log("COMMAND, Y U NO LOG FIRST?").Build()));
   1462     EXPECT_THAT(out, StrEq("stdout\n"));
   1463     EXPECT_THAT(err, StrEq("COMMAND, Y U NO LOG FIRST?stderr\n"));
   1464 }
   1465 
   1466 TEST_F(DumpstateUtilTest, RunCommandRedirectStderr) {
   1467     CreateFd("RunCommandRedirectStderr.txt");
   1468     EXPECT_EQ(0, RunCommand("", {kSimpleCommand},
   1469                             CommandOptions::WithTimeout(10).RedirectStderr().Build()));
   1470     EXPECT_THAT(out, IsEmpty());
   1471     EXPECT_THAT(err, StrEq("stdout\nstderr\n"));
   1472 }
   1473 
   1474 TEST_F(DumpstateUtilTest, RunCommandDryRun) {
   1475     CreateFd("RunCommandDryRun.txt");
   1476     SetDryRun(true);
   1477     EXPECT_EQ(0, RunCommand("I AM GROOT", {kSimpleCommand}));
   1478     EXPECT_THAT(out, StrEq(android::base::StringPrintf(
   1479                          "------ I AM GROOT (%s) ------\n\t(skipped on dry run)\n",
   1480                          kSimpleCommand.c_str())));
   1481     EXPECT_THAT(err, IsEmpty());
   1482 }
   1483 
   1484 TEST_F(DumpstateUtilTest, RunCommandDryRunNoTitle) {
   1485     CreateFd("RunCommandDryRun.txt");
   1486     SetDryRun(true);
   1487     EXPECT_EQ(0, RunCommand("", {kSimpleCommand}));
   1488     EXPECT_THAT(
   1489         out, StrEq(android::base::StringPrintf("%s: skipped on dry run\n", kSimpleCommand.c_str())));
   1490     EXPECT_THAT(err, IsEmpty());
   1491 }
   1492 
   1493 TEST_F(DumpstateUtilTest, RunCommandDryRunAlways) {
   1494     CreateFd("RunCommandDryRunAlways.txt");
   1495     SetDryRun(true);
   1496     EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(10).Always().Build()));
   1497     EXPECT_THAT(out, StrEq("stdout\n"));
   1498     EXPECT_THAT(err, StrEq("stderr\n"));
   1499 }
   1500 
   1501 TEST_F(DumpstateUtilTest, RunCommandNotFound) {
   1502     CreateFd("RunCommandNotFound.txt");
   1503     EXPECT_NE(0, RunCommand("", {"/there/cannot/be/such/command"}));
   1504     EXPECT_THAT(out, StartsWith("*** command '/there/cannot/be/such/command' failed: exit code"));
   1505     EXPECT_THAT(err, StartsWith("execvp on command '/there/cannot/be/such/command' failed"));
   1506 }
   1507 
   1508 TEST_F(DumpstateUtilTest, RunCommandFails) {
   1509     CreateFd("RunCommandFails.txt");
   1510     EXPECT_EQ(42, RunCommand("", {kSimpleCommand, "--exit", "42"}));
   1511     EXPECT_THAT(out, StrEq("stdout\n*** command '" + kSimpleCommand +
   1512                            " --exit 42' failed: exit code 42\n"));
   1513     EXPECT_THAT(err, StrEq("stderr\n*** command '" + kSimpleCommand +
   1514                            " --exit 42' failed: exit code 42\n"));
   1515 }
   1516 
   1517 TEST_F(DumpstateUtilTest, RunCommandCrashes) {
   1518     CreateFd("RunCommandCrashes.txt");
   1519     EXPECT_NE(0, RunCommand("", {kSimpleCommand, "--crash"}));
   1520     // We don't know the exit code, so check just the prefix.
   1521     EXPECT_THAT(
   1522         out, StartsWith("stdout\n*** command '" + kSimpleCommand + " --crash' failed: exit code"));
   1523     EXPECT_THAT(
   1524         err, StartsWith("stderr\n*** command '" + kSimpleCommand + " --crash' failed: exit code"));
   1525 }
   1526 
   1527 TEST_F(DumpstateUtilTest, RunCommandTimesoutWithSec) {
   1528     CreateFd("RunCommandTimesout.txt");
   1529     EXPECT_EQ(-1, RunCommand("", {kSimpleCommand, "--sleep", "2"},
   1530                              CommandOptions::WithTimeout(1).Build()));
   1531     EXPECT_THAT(out, StartsWith("stdout line1\n*** command '" + kSimpleCommand +
   1532                                 " --sleep 2' timed out after 1"));
   1533     EXPECT_THAT(err, StartsWith("sleeping for 2s\n*** command '" + kSimpleCommand +
   1534                                 " --sleep 2' timed out after 1"));
   1535 }
   1536 
   1537 TEST_F(DumpstateUtilTest, RunCommandTimesoutWithMsec) {
   1538     CreateFd("RunCommandTimesout.txt");
   1539     EXPECT_EQ(-1, RunCommand("", {kSimpleCommand, "--sleep", "2"},
   1540                              CommandOptions::WithTimeoutInMs(1000).Build()));
   1541     EXPECT_THAT(out, StartsWith("stdout line1\n*** command '" + kSimpleCommand +
   1542                                 " --sleep 2' timed out after 1"));
   1543     EXPECT_THAT(err, StartsWith("sleeping for 2s\n*** command '" + kSimpleCommand +
   1544                                 " --sleep 2' timed out after 1"));
   1545 }
   1546 
   1547 
   1548 TEST_F(DumpstateUtilTest, RunCommandIsKilled) {
   1549     CreateFd("RunCommandIsKilled.txt");
   1550     CaptureStderr();
   1551 
   1552     std::thread t([=]() {
   1553         EXPECT_EQ(SIGTERM, RunCommandToFd(fd, "", {kSimpleCommand, "--pid", "--sleep", "20"},
   1554                                           CommandOptions::WithTimeout(100).Always().Build()));
   1555     });
   1556 
   1557     // Capture pid and pre-sleep output.
   1558     sleep(1);  // Wait a little bit to make sure pid and 1st line were printed.
   1559     std::string err = GetCapturedStderr();
   1560     EXPECT_THAT(err, StrEq("sleeping for 20s\n"));
   1561 
   1562     CaptureFdOut();
   1563     std::vector<std::string> lines = android::base::Split(out, "\n");
   1564     ASSERT_EQ(3, (int)lines.size()) << "Invalid lines before sleep: " << out;
   1565 
   1566     int pid = atoi(lines[0].c_str());
   1567     EXPECT_THAT(lines[1], StrEq("stdout line1"));
   1568     EXPECT_THAT(lines[2], IsEmpty());  // \n
   1569 
   1570     // Then kill the process.
   1571     CaptureFdOut();
   1572     CaptureStderr();
   1573     ASSERT_EQ(0, kill(pid, SIGTERM)) << "failed to kill pid " << pid;
   1574     t.join();
   1575 
   1576     // Finally, check output after murder.
   1577     CaptureFdOut();
   1578     err = GetCapturedStderr();
   1579 
   1580     // out starts with the pid, which is an unknown
   1581     EXPECT_THAT(out, EndsWith("stdout line1\n*** command '" + kSimpleCommand +
   1582                               " --pid --sleep 20' failed: killed by signal 15\n"));
   1583     EXPECT_THAT(err, StrEq("*** command '" + kSimpleCommand +
   1584                            " --pid --sleep 20' failed: killed by signal 15\n"));
   1585 }
   1586 
   1587 TEST_F(DumpstateUtilTest, RunCommandAsRootUserBuild) {
   1588     if (!IsStandalone()) {
   1589         // TODO: temporarily disabled because it might cause other tests to fail after dropping
   1590         // to Shell - need to refactor tests to avoid this problem)
   1591         MYLOGE("Skipping DumpstateUtilTest.RunCommandAsRootUserBuild() on test suite\n")
   1592         return;
   1593     }
   1594     CreateFd("RunCommandAsRootUserBuild.txt");
   1595     if (!PropertiesHelper::IsUserBuild()) {
   1596         // Emulates user build if necessarily.
   1597         SetBuildType("user");
   1598     }
   1599 
   1600     DropRoot();
   1601 
   1602     EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).AsRoot().Build()));
   1603 
   1604     // We don't know the exact path of su, so we just check for the 'root ...' commands
   1605     EXPECT_THAT(out, StartsWith("Skipping"));
   1606     EXPECT_THAT(out, EndsWith("root " + kSimpleCommand + "' on user build.\n"));
   1607     EXPECT_THAT(err, IsEmpty());
   1608 }
   1609 
   1610 TEST_F(DumpstateUtilTest, RunCommandAsRootNonUserBuild) {
   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.RunCommandAsRootNonUserBuild() on test suite\n")
   1615         return;
   1616     }
   1617     CreateFd("RunCommandAsRootNonUserBuild.txt");
   1618     if (PropertiesHelper::IsUserBuild()) {
   1619         ALOGI("Skipping RunCommandAsRootNonUserBuild on user builds\n");
   1620         return;
   1621     }
   1622 
   1623     DropRoot();
   1624 
   1625     EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
   1626                             CommandOptions::WithTimeout(1).AsRoot().Build()));
   1627 
   1628     EXPECT_THAT(out, StrEq("0\nstdout\n"));
   1629     EXPECT_THAT(err, StrEq("stderr\n"));
   1630 }
   1631 
   1632 
   1633 TEST_F(DumpstateUtilTest, RunCommandAsRootIfAvailableOnUserBuild) {
   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.RunCommandAsRootIfAvailableOnUserBuild() on test suite\n")
   1638         return;
   1639     }
   1640     CreateFd("RunCommandAsRootIfAvailableOnUserBuild.txt");
   1641     if (!PropertiesHelper::IsUserBuild()) {
   1642         // Emulates user build if necessarily.
   1643         SetBuildType("user");
   1644     }
   1645 
   1646     DropRoot();
   1647 
   1648     EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
   1649                             CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
   1650 
   1651     EXPECT_THAT(out, StrEq("2000\nstdout\n"));
   1652     EXPECT_THAT(err, StrEq("stderr\n"));
   1653 }
   1654 
   1655 TEST_F(DumpstateUtilTest, RunCommandAsRootIfAvailableOnDebugBuild) {
   1656     if (!IsStandalone()) {
   1657         // TODO: temporarily disabled because it might cause other tests to fail after dropping
   1658         // to Shell - need to refactor tests to avoid this problem)
   1659         MYLOGE("Skipping DumpstateUtilTest.RunCommandAsRootIfAvailableOnDebugBuild() on test suite\n")
   1660         return;
   1661     }
   1662     CreateFd("RunCommandAsRootIfAvailableOnDebugBuild.txt");
   1663     if (PropertiesHelper::IsUserBuild()) {
   1664         ALOGI("Skipping RunCommandAsRootNonUserBuild on user builds\n");
   1665         return;
   1666     }
   1667 
   1668     DropRoot();
   1669 
   1670     EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
   1671                             CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
   1672 
   1673     EXPECT_THAT(out, StrEq("0\nstdout\n"));
   1674     EXPECT_THAT(err, StrEq("stderr\n"));
   1675 }
   1676 
   1677 TEST_F(DumpstateUtilTest, RunCommandDropRoot) {
   1678     if (!IsStandalone()) {
   1679         // TODO: temporarily disabled because it might cause other tests to fail after dropping
   1680         // to Shell - need to refactor tests to avoid this problem)
   1681         MYLOGE("Skipping DumpstateUtilTest.RunCommandDropRoot() on test suite\n")
   1682         return;
   1683     }
   1684     CreateFd("RunCommandDropRoot.txt");
   1685     // First check root case - only available when running with 'adb root'.
   1686     uid_t uid = getuid();
   1687     if (uid == 0) {
   1688         EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"}));
   1689         EXPECT_THAT(out, StrEq("0\nstdout\n"));
   1690         EXPECT_THAT(err, StrEq("stderr\n"));
   1691         return;
   1692     }
   1693     // Then run dropping root.
   1694     EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
   1695                             CommandOptions::WithTimeout(1).DropRoot().Build()));
   1696     EXPECT_THAT(out, StrEq("2000\nstdout\n"));
   1697     EXPECT_THAT(err, StrEq("drop_root_user(): already running as Shell\nstderr\n"));
   1698 }
   1699 
   1700 TEST_F(DumpstateUtilTest, DumpFileNotFoundNoTitle) {
   1701     CreateFd("DumpFileNotFound.txt");
   1702     EXPECT_EQ(-1, DumpFile("", "/I/cant/believe/I/exist"));
   1703     EXPECT_THAT(out,
   1704                 StrEq("*** Error dumping /I/cant/believe/I/exist: No such file or directory\n"));
   1705     EXPECT_THAT(err, IsEmpty());
   1706 }
   1707 
   1708 TEST_F(DumpstateUtilTest, DumpFileNotFoundWithTitle) {
   1709     CreateFd("DumpFileNotFound.txt");
   1710     EXPECT_EQ(-1, DumpFile("Y U NO EXIST?", "/I/cant/believe/I/exist"));
   1711     EXPECT_THAT(out, StrEq("*** Error dumping /I/cant/believe/I/exist (Y U NO EXIST?): No such "
   1712                            "file or directory\n"));
   1713     EXPECT_THAT(err, IsEmpty());
   1714 }
   1715 
   1716 TEST_F(DumpstateUtilTest, DumpFileSingleLine) {
   1717     CreateFd("DumpFileSingleLine.txt");
   1718     EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
   1719     EXPECT_THAT(err, IsEmpty());
   1720     EXPECT_THAT(out, StrEq("I AM LINE1\n"));  // dumpstate adds missing newline
   1721 }
   1722 
   1723 TEST_F(DumpstateUtilTest, DumpFileSingleLineWithNewLine) {
   1724     CreateFd("DumpFileSingleLineWithNewLine.txt");
   1725     EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line-with-newline.txt"));
   1726     EXPECT_THAT(err, IsEmpty());
   1727     EXPECT_THAT(out, StrEq("I AM LINE1\n"));
   1728 }
   1729 
   1730 TEST_F(DumpstateUtilTest, DumpFileMultipleLines) {
   1731     CreateFd("DumpFileMultipleLines.txt");
   1732     EXPECT_EQ(0, DumpFile("", kTestDataPath + "multiple-lines.txt"));
   1733     EXPECT_THAT(err, IsEmpty());
   1734     EXPECT_THAT(out, StrEq("I AM LINE1\nI AM LINE2\nI AM LINE3\n"));
   1735 }
   1736 
   1737 TEST_F(DumpstateUtilTest, DumpFileMultipleLinesWithNewLine) {
   1738     CreateFd("DumpFileMultipleLinesWithNewLine.txt");
   1739     EXPECT_EQ(0, DumpFile("", kTestDataPath + "multiple-lines-with-newline.txt"));
   1740     EXPECT_THAT(err, IsEmpty());
   1741     EXPECT_THAT(out, StrEq("I AM LINE1\nI AM LINE2\nI AM LINE3\n"));
   1742 }
   1743 
   1744 TEST_F(DumpstateUtilTest, DumpFileOnDryRunNoTitle) {
   1745     CreateFd("DumpFileOnDryRun.txt");
   1746     SetDryRun(true);
   1747     std::string path = kTestDataPath + "single-line.txt";
   1748     EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
   1749     EXPECT_THAT(err, IsEmpty());
   1750     EXPECT_THAT(out, StrEq(path + ": skipped on dry run\n"));
   1751 }
   1752 
   1753 TEST_F(DumpstateUtilTest, DumpFileOnDryRun) {
   1754     CreateFd("DumpFileOnDryRun.txt");
   1755     SetDryRun(true);
   1756     std::string path = kTestDataPath + "single-line.txt";
   1757     EXPECT_EQ(0, DumpFile("Might as well dump. Dump!", kTestDataPath + "single-line.txt"));
   1758     EXPECT_THAT(err, IsEmpty());
   1759     EXPECT_THAT(
   1760         out, StartsWith("------ Might as well dump. Dump! (" + kTestDataPath + "single-line.txt:"));
   1761     EXPECT_THAT(out, EndsWith("skipped on dry run\n"));
   1762 }
   1763 
   1764 TEST_F(DumpstateUtilTest, FindingPidWithExistingProcess) {
   1765     // init process always has pid 1.
   1766     EXPECT_EQ(1, FindPidOfProcess("init"));
   1767     EXPECT_THAT(err, IsEmpty());
   1768 }
   1769 
   1770 TEST_F(DumpstateUtilTest, FindingPidWithNotExistingProcess) {
   1771     // find the process with abnormal name.
   1772     EXPECT_EQ(-1, FindPidOfProcess("abcdef12345-543"));
   1773     EXPECT_THAT(err, StrEq("can't find the pid\n"));
   1774 }
   1775 
   1776 }  // namespace dumpstate
   1777 }  // namespace os
   1778 }  // namespace android
   1779