dumpstate_test.cpp revision 009ecbbd3fcfd06735b0102f0342fc7e60166d9b
14c2d66379753e2b7680811726424026b9e54b18aFelipe Leme/* 24c2d66379753e2b7680811726424026b9e54b18aFelipe Leme * Copyright (C) 2016 The Android Open Source Project 34c2d66379753e2b7680811726424026b9e54b18aFelipe Leme * 44c2d66379753e2b7680811726424026b9e54b18aFelipe Leme * Licensed under the Apache License, Version 2.0 (the "License"); 54c2d66379753e2b7680811726424026b9e54b18aFelipe Leme * you may not use this file except in compliance with the License. 64c2d66379753e2b7680811726424026b9e54b18aFelipe Leme * You may obtain a copy of the License at 74c2d66379753e2b7680811726424026b9e54b18aFelipe Leme * 84c2d66379753e2b7680811726424026b9e54b18aFelipe Leme * http://www.apache.org/licenses/LICENSE-2.0 94c2d66379753e2b7680811726424026b9e54b18aFelipe Leme * 104c2d66379753e2b7680811726424026b9e54b18aFelipe Leme * Unless required by applicable law or agreed to in writing, software 114c2d66379753e2b7680811726424026b9e54b18aFelipe Leme * distributed under the License is distributed on an "AS IS" BASIS, 124c2d66379753e2b7680811726424026b9e54b18aFelipe Leme * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134c2d66379753e2b7680811726424026b9e54b18aFelipe Leme * See the License for the specific language governing permissions and 144c2d66379753e2b7680811726424026b9e54b18aFelipe Leme * limitations under the License. 154c2d66379753e2b7680811726424026b9e54b18aFelipe Leme */ 164c2d66379753e2b7680811726424026b9e54b18aFelipe Leme 1775876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme#define LOG_TAG "dumpstate" 1875876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme#include <cutils/log.h> 1975876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme 2075876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme#include "DumpstateService.h" 2175876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme#include "android/os/BnDumpstate.h" 224c2d66379753e2b7680811726424026b9e54b18aFelipe Leme#include "dumpstate.h" 234c2d66379753e2b7680811726424026b9e54b18aFelipe Leme 244c2d66379753e2b7680811726424026b9e54b18aFelipe Leme#include <gmock/gmock.h> 254c2d66379753e2b7680811726424026b9e54b18aFelipe Leme#include <gtest/gtest.h> 264c2d66379753e2b7680811726424026b9e54b18aFelipe Leme 274c2d66379753e2b7680811726424026b9e54b18aFelipe Leme#include <libgen.h> 28fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme#include <signal.h> 29fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme#include <sys/types.h> 304c2d66379753e2b7680811726424026b9e54b18aFelipe Leme#include <unistd.h> 31fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme#include <thread> 324c2d66379753e2b7680811726424026b9e54b18aFelipe Leme 334c2d66379753e2b7680811726424026b9e54b18aFelipe Leme#include <android-base/file.h> 34d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme#include <android-base/properties.h> 35d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme#include <android-base/stringprintf.h> 36fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme#include <android-base/strings.h> 374c2d66379753e2b7680811726424026b9e54b18aFelipe Leme 3875876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Lemeusing namespace android; 39d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme 404c2d66379753e2b7680811726424026b9e54b18aFelipe Lemeusing ::testing::EndsWith; 41009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Lemeusing ::testing::IsNull; 424c2d66379753e2b7680811726424026b9e54b18aFelipe Lemeusing ::testing::IsEmpty; 43009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Lemeusing ::testing::NotNull; 444c2d66379753e2b7680811726424026b9e54b18aFelipe Lemeusing ::testing::StrEq; 454c2d66379753e2b7680811726424026b9e54b18aFelipe Lemeusing ::testing::StartsWith; 464c2d66379753e2b7680811726424026b9e54b18aFelipe Lemeusing ::testing::Test; 474c2d66379753e2b7680811726424026b9e54b18aFelipe Lemeusing ::testing::internal::CaptureStderr; 484c2d66379753e2b7680811726424026b9e54b18aFelipe Lemeusing ::testing::internal::CaptureStdout; 494c2d66379753e2b7680811726424026b9e54b18aFelipe Lemeusing ::testing::internal::GetCapturedStderr; 504c2d66379753e2b7680811726424026b9e54b18aFelipe Lemeusing ::testing::internal::GetCapturedStdout; 514c2d66379753e2b7680811726424026b9e54b18aFelipe Leme 5275876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Lemeusing os::DumpstateService; 5375876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Lemeusing os::IDumpstateListener; 54009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Lemeusing os::IDumpstateToken; 5575876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme 564c2d66379753e2b7680811726424026b9e54b18aFelipe Leme// Not used on test cases yet... 574c2d66379753e2b7680811726424026b9e54b18aFelipe Lemevoid dumpstate_board(void) { 584c2d66379753e2b7680811726424026b9e54b18aFelipe Leme} 594c2d66379753e2b7680811726424026b9e54b18aFelipe Leme 6075876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Lemeclass DumpstateListenerMock : public IDumpstateListener { 6175876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme public: 6275876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme MOCK_METHOD1(onProgressUpdated, binder::Status(int32_t progress)); 6375876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme MOCK_METHOD1(onMaxProgressUpdated, binder::Status(int32_t max_progress)); 6475876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme 6575876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme protected: 6675876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme MOCK_METHOD0(onAsBinder, IBinder*()); 6775876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme}; 6875876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme 697447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme// Base class for all tests in this file 707447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Lemeclass DumpstateBaseTest : public Test { 717447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme protected: 727447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme const std::string kTestPath = dirname(android::base::GetExecutablePath().c_str()); 737447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme const std::string kFixturesPath = kTestPath + "/../dumpstate_test_fixture/"; 747447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme const std::string kTestDataPath = kFixturesPath + "/testdata/"; 757447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme const std::string kSimpleCommand = kFixturesPath + "dumpstate_test_fixture"; 767447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme const std::string kEchoCommand = "/system/bin/echo"; 777447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme 787447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme /* 797447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme * Copies a text file fixture to a temporary file, returning it's path. 807447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme * 817447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme * Useful in cases where the test case changes the content of the tile. 827447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme */ 837447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme std::string CopyTextFileFixture(const std::string& relative_name) { 847447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme std::string from = kTestDataPath + relative_name; 857447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme // Not using TemporaryFile because it's deleted at the end, and it's useful to keep it 867447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme // around for poking when the test fails. 877447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme std::string to = kTestDataPath + relative_name + ".tmp"; 887447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme ALOGD("CopyTextFileFixture: from %s to %s\n", from.c_str(), to.c_str()); 897447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme android::base::RemoveFileIfExists(to); 907447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme CopyTextFile(from, to); 917447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme return to.c_str(); 927447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme } 937447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme 947447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme private: 957447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme // Need a function that returns void to use assertions - 967447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme // https://github.com/google/googletest/blob/master/googletest/docs/AdvancedGuide.md#assertion-placement 977447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme void CopyTextFile(const std::string& from, const std::string& to) { 987447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme std::string content; 997447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme ASSERT_TRUE(android::base::ReadFileToString(from, &content)) << "could not read from " 1007447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme << from; 1017447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme ASSERT_TRUE(android::base::WriteStringToFile(content, to)) << "could not write to " << to; 1027447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme } 1037447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme}; 1047447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme 1057447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Lemeclass DumpstateTest : public DumpstateBaseTest { 1064c2d66379753e2b7680811726424026b9e54b18aFelipe Leme public: 1074c2d66379753e2b7680811726424026b9e54b18aFelipe Leme void SetUp() { 1084c2d66379753e2b7680811726424026b9e54b18aFelipe Leme SetDryRun(false); 109d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme SetBuildType(android::base::GetProperty("ro.build.type", "(unknown)")); 1107447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme ds.progress_.reset(new Progress()); 1119a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme ds.update_progress_ = false; 112009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme ds.update_progress_threshold_ = 0; 1134c2d66379753e2b7680811726424026b9e54b18aFelipe Leme } 1144c2d66379753e2b7680811726424026b9e54b18aFelipe Leme 1154c2d66379753e2b7680811726424026b9e54b18aFelipe Leme // Runs a command and capture `stdout` and `stderr`. 1169a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme int RunCommand(const std::string& title, const std::vector<std::string>& full_command, 1174c2d66379753e2b7680811726424026b9e54b18aFelipe Leme const CommandOptions& options = CommandOptions::DEFAULT) { 1184c2d66379753e2b7680811726424026b9e54b18aFelipe Leme CaptureStdout(); 1194c2d66379753e2b7680811726424026b9e54b18aFelipe Leme CaptureStderr(); 1209a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme int status = ds.RunCommand(title, full_command, options); 1214c2d66379753e2b7680811726424026b9e54b18aFelipe Leme out = GetCapturedStdout(); 1224c2d66379753e2b7680811726424026b9e54b18aFelipe Leme err = GetCapturedStderr(); 1234c2d66379753e2b7680811726424026b9e54b18aFelipe Leme return status; 1244c2d66379753e2b7680811726424026b9e54b18aFelipe Leme } 1254c2d66379753e2b7680811726424026b9e54b18aFelipe Leme 126cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe Leme // Dumps a file and capture `stdout` and `stderr`. 127cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe Leme int DumpFile(const std::string& title, const std::string& path) { 128cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe Leme CaptureStdout(); 129cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe Leme CaptureStderr(); 130cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe Leme int status = ds.DumpFile(title, path); 131cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe Leme out = GetCapturedStdout(); 132cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe Leme err = GetCapturedStderr(); 133cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe Leme return status; 134cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe Leme } 135cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe Leme 1369a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme void SetDryRun(bool dry_run) { 1379a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme ALOGD("Setting dry_run_ to %s\n", dry_run ? "true" : "false"); 1389a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme ds.dry_run_ = dry_run; 139d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme } 140d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme 1419a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme void SetBuildType(const std::string& build_type) { 1429a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme ALOGD("Setting build_type_ to '%s'\n", build_type.c_str()); 1439a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme ds.build_type_ = build_type; 144d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme } 145d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme 146d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme bool IsUserBuild() { 147d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme return "user" == android::base::GetProperty("ro.build.type", "(unknown)"); 148d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme } 149d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme 150d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme void DropRoot() { 151d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme drop_root_user(); 152d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme uid_t uid = getuid(); 153d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme ASSERT_EQ(2000, (int)uid); 154d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme } 155d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme 156009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme void SetProgress(long progress, long initial_max, long threshold = 0) { 1577447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme ds.update_progress_ = true; 158009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme ds.update_progress_threshold_ = threshold; 159009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme ds.last_updated_progress_ = 0; 1607447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme ds.progress_.reset(new Progress(initial_max, progress, 1.2)); 1617447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme } 1627447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme 163009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme std::string GetProgressMessage(const std::string& listener_name, int progress, int max, 164009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme int old_max = 0, bool update_progress = true) { 1657447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(progress, ds.progress_->Get()) << "invalid progress"; 1667447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(max, ds.progress_->GetMax()) << "invalid max"; 167d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme 1687447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme bool max_increased = old_max > 0; 169d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme 170009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme std::string message = ""; 1719a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme if (max_increased) { 172009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme message = 1737447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme android::base::StringPrintf("Adjusting max progress from %d to %d\n", old_max, max); 174d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme } 175d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme 176009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme if (update_progress) { 177009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme message += android::base::StringPrintf("Setting progress (%s): %d/%d\n", 178009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme listener_name.c_str(), progress, max); 17975876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme } 18075876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme 181009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme return message; 182d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme } 183d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme 1844c2d66379753e2b7680811726424026b9e54b18aFelipe Leme // `stdout` and `stderr` from the last command ran. 1854c2d66379753e2b7680811726424026b9e54b18aFelipe Leme std::string out, err; 1864c2d66379753e2b7680811726424026b9e54b18aFelipe Leme 187fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme Dumpstate& ds = Dumpstate::GetInstance(); 1884c2d66379753e2b7680811726424026b9e54b18aFelipe Leme}; 1894c2d66379753e2b7680811726424026b9e54b18aFelipe Leme 1904c2d66379753e2b7680811726424026b9e54b18aFelipe LemeTEST_F(DumpstateTest, RunCommandNoArgs) { 1914c2d66379753e2b7680811726424026b9e54b18aFelipe Leme EXPECT_EQ(-1, RunCommand("", {})); 1924c2d66379753e2b7680811726424026b9e54b18aFelipe Leme} 1934c2d66379753e2b7680811726424026b9e54b18aFelipe Leme 1944c2d66379753e2b7680811726424026b9e54b18aFelipe LemeTEST_F(DumpstateTest, RunCommandNoTitle) { 1957447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(0, RunCommand("", {kSimpleCommand})); 1964c2d66379753e2b7680811726424026b9e54b18aFelipe Leme EXPECT_THAT(out, StrEq("stdout\n")); 1974c2d66379753e2b7680811726424026b9e54b18aFelipe Leme EXPECT_THAT(err, StrEq("stderr\n")); 1984c2d66379753e2b7680811726424026b9e54b18aFelipe Leme} 1994c2d66379753e2b7680811726424026b9e54b18aFelipe Leme 2004c2d66379753e2b7680811726424026b9e54b18aFelipe LemeTEST_F(DumpstateTest, RunCommandWithTitle) { 2017447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(0, RunCommand("I AM GROOT", {kSimpleCommand})); 2024c2d66379753e2b7680811726424026b9e54b18aFelipe Leme EXPECT_THAT(err, StrEq("stderr\n")); 2034c2d66379753e2b7680811726424026b9e54b18aFelipe Leme // We don't know the exact duration, so we check the prefix and suffix 204fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme EXPECT_THAT(out, 2057447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme StartsWith("------ I AM GROOT (" + kSimpleCommand + ") ------\nstdout\n------")); 2064c2d66379753e2b7680811726424026b9e54b18aFelipe Leme EXPECT_THAT(out, EndsWith("s was the duration of 'I AM GROOT' ------\n")); 2074c2d66379753e2b7680811726424026b9e54b18aFelipe Leme} 2084c2d66379753e2b7680811726424026b9e54b18aFelipe Leme 209fd8affa8840d2d9f7f320201521a702919c677ffFelipe LemeTEST_F(DumpstateTest, RunCommandWithLoggingMessage) { 2104c2d66379753e2b7680811726424026b9e54b18aFelipe Leme EXPECT_EQ( 2117447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme 0, RunCommand("", {kSimpleCommand}, 212fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme CommandOptions::WithTimeout(10).Log("COMMAND, Y U NO LOG FIRST?").Build())); 213fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme EXPECT_THAT(out, StrEq("stdout\n")); 214fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme EXPECT_THAT(err, StrEq("COMMAND, Y U NO LOG FIRST?stderr\n")); 215fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme} 216fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme 217fd8affa8840d2d9f7f320201521a702919c677ffFelipe LemeTEST_F(DumpstateTest, RunCommandRedirectStderr) { 2187447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, 219fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme CommandOptions::WithTimeout(10).RedirectStderr().Build())); 2204c2d66379753e2b7680811726424026b9e54b18aFelipe Leme EXPECT_THAT(out, IsEmpty()); 221fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme EXPECT_THAT(err, StrEq("stdout\nstderr\n")); 2224c2d66379753e2b7680811726424026b9e54b18aFelipe Leme} 2234c2d66379753e2b7680811726424026b9e54b18aFelipe Leme 2244c2d66379753e2b7680811726424026b9e54b18aFelipe LemeTEST_F(DumpstateTest, RunCommandWithOneArg) { 2257447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(0, RunCommand("", {kEchoCommand, "one"})); 2264c2d66379753e2b7680811726424026b9e54b18aFelipe Leme EXPECT_THAT(err, IsEmpty()); 2274c2d66379753e2b7680811726424026b9e54b18aFelipe Leme EXPECT_THAT(out, StrEq("one\n")); 2284c2d66379753e2b7680811726424026b9e54b18aFelipe Leme} 2294c2d66379753e2b7680811726424026b9e54b18aFelipe Leme 230fd8affa8840d2d9f7f320201521a702919c677ffFelipe LemeTEST_F(DumpstateTest, RunCommandWithMultipleArgs) { 2317447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(0, RunCommand("", {kEchoCommand, "one", "is", "the", "loniest", "number"})); 2324c2d66379753e2b7680811726424026b9e54b18aFelipe Leme EXPECT_THAT(err, IsEmpty()); 2334c2d66379753e2b7680811726424026b9e54b18aFelipe Leme EXPECT_THAT(out, StrEq("one is the loniest number\n")); 2344c2d66379753e2b7680811726424026b9e54b18aFelipe Leme} 2354c2d66379753e2b7680811726424026b9e54b18aFelipe Leme 2364c2d66379753e2b7680811726424026b9e54b18aFelipe LemeTEST_F(DumpstateTest, RunCommandDryRun) { 2374c2d66379753e2b7680811726424026b9e54b18aFelipe Leme SetDryRun(true); 2387447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(0, RunCommand("I AM GROOT", {kSimpleCommand})); 2394c2d66379753e2b7680811726424026b9e54b18aFelipe Leme // We don't know the exact duration, so we check the prefix and suffix 2407447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_THAT(out, StartsWith("------ I AM GROOT (" + kSimpleCommand + 2414c2d66379753e2b7680811726424026b9e54b18aFelipe Leme ") ------\n\t(skipped on dry run)\n------")); 2424c2d66379753e2b7680811726424026b9e54b18aFelipe Leme EXPECT_THAT(out, EndsWith("s was the duration of 'I AM GROOT' ------\n")); 2434c2d66379753e2b7680811726424026b9e54b18aFelipe Leme EXPECT_THAT(err, IsEmpty()); 2444c2d66379753e2b7680811726424026b9e54b18aFelipe Leme} 2454c2d66379753e2b7680811726424026b9e54b18aFelipe Leme 2464c2d66379753e2b7680811726424026b9e54b18aFelipe LemeTEST_F(DumpstateTest, RunCommandDryRunNoTitle) { 2474c2d66379753e2b7680811726424026b9e54b18aFelipe Leme SetDryRun(true); 2487447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(0, RunCommand("", {kSimpleCommand})); 2494c2d66379753e2b7680811726424026b9e54b18aFelipe Leme EXPECT_THAT(out, IsEmpty()); 2504c2d66379753e2b7680811726424026b9e54b18aFelipe Leme EXPECT_THAT(err, IsEmpty()); 2514c2d66379753e2b7680811726424026b9e54b18aFelipe Leme} 2524c2d66379753e2b7680811726424026b9e54b18aFelipe Leme 2534c2d66379753e2b7680811726424026b9e54b18aFelipe LemeTEST_F(DumpstateTest, RunCommandDryRunAlways) { 2544c2d66379753e2b7680811726424026b9e54b18aFelipe Leme SetDryRun(true); 2557447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(10).Always().Build())); 2564c2d66379753e2b7680811726424026b9e54b18aFelipe Leme EXPECT_THAT(out, StrEq("stdout\n")); 2574c2d66379753e2b7680811726424026b9e54b18aFelipe Leme EXPECT_THAT(err, StrEq("stderr\n")); 2584c2d66379753e2b7680811726424026b9e54b18aFelipe Leme} 2594c2d66379753e2b7680811726424026b9e54b18aFelipe Leme 260fd8affa8840d2d9f7f320201521a702919c677ffFelipe LemeTEST_F(DumpstateTest, RunCommandNotFound) { 261fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme EXPECT_NE(0, RunCommand("", {"/there/cannot/be/such/command"})); 262fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme EXPECT_THAT(out, StartsWith("*** command '/there/cannot/be/such/command' failed: exit code")); 263fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme EXPECT_THAT(err, StartsWith("execvp on command '/there/cannot/be/such/command' failed")); 264fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme} 265fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme 266fd8affa8840d2d9f7f320201521a702919c677ffFelipe LemeTEST_F(DumpstateTest, RunCommandFails) { 2677447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(42, RunCommand("", {kSimpleCommand, "--exit", "42"})); 2687447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_THAT(out, StrEq("stdout\n*** command '" + kSimpleCommand + 2699a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme " --exit 42' failed: exit code 42\n")); 2707447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_THAT(err, StrEq("stderr\n*** command '" + kSimpleCommand + 2719a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme " --exit 42' failed: exit code 42\n")); 272fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme} 273fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme 274fd8affa8840d2d9f7f320201521a702919c677ffFelipe LemeTEST_F(DumpstateTest, RunCommandCrashes) { 2757447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_NE(0, RunCommand("", {kSimpleCommand, "--crash"})); 276fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme // We don't know the exit code, so check just the prefix. 277fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme EXPECT_THAT( 2787447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme out, StartsWith("stdout\n*** command '" + kSimpleCommand + " --crash' failed: exit code")); 279fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme EXPECT_THAT( 2807447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme err, StartsWith("stderr\n*** command '" + kSimpleCommand + " --crash' failed: exit code")); 281fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme} 282fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme 283fd8affa8840d2d9f7f320201521a702919c677ffFelipe LemeTEST_F(DumpstateTest, RunCommandTimesout) { 2847447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(-1, RunCommand("", {kSimpleCommand, "--sleep", "2"}, 285fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme CommandOptions::WithTimeout(1).Build())); 2867447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_THAT(out, StartsWith("stdout line1\n*** command '" + kSimpleCommand + 287fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme " --sleep 2' timed out after 1")); 2887447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_THAT(err, StartsWith("sleeping for 2s\n*** command '" + kSimpleCommand + 289fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme " --sleep 2' timed out after 1")); 290fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme} 291fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme 292fd8affa8840d2d9f7f320201521a702919c677ffFelipe LemeTEST_F(DumpstateTest, RunCommandIsKilled) { 293fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme CaptureStdout(); 294fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme CaptureStderr(); 295fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme 296fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme std::thread t([=]() { 2977447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(SIGTERM, ds.RunCommand("", {kSimpleCommand, "--pid", "--sleep", "20"}, 298fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme CommandOptions::WithTimeout(100).Always().Build())); 299fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme }); 300fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme 301fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme // Capture pid and pre-sleep output. 302fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme sleep(1); // Wait a little bit to make sure pid and 1st line were printed. 303fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme std::string err = GetCapturedStderr(); 304fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme EXPECT_THAT(err, StrEq("sleeping for 20s\n")); 305fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme 306fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme std::string out = GetCapturedStdout(); 307fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme std::vector<std::string> lines = android::base::Split(out, "\n"); 308fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme ASSERT_EQ(3, (int)lines.size()) << "Invalid lines before sleep: " << out; 309fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme 310fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme int pid = atoi(lines[0].c_str()); 311fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme EXPECT_THAT(lines[1], StrEq("stdout line1")); 312fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme EXPECT_THAT(lines[2], IsEmpty()); // \n 313fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme 314fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme // Then kill the process. 315fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme CaptureStdout(); 316fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme CaptureStderr(); 317fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme ASSERT_EQ(0, kill(pid, SIGTERM)) << "failed to kill pid " << pid; 318fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme t.join(); 319fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme 320fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme // Finally, check output after murder. 321fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme out = GetCapturedStdout(); 322fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme err = GetCapturedStderr(); 323fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme 3247447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_THAT(out, StrEq("*** command '" + kSimpleCommand + 325fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme " --pid --sleep 20' failed: killed by signal 15\n")); 3267447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_THAT(err, StrEq("*** command '" + kSimpleCommand + 327fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme " --pid --sleep 20' failed: killed by signal 15\n")); 328fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme} 329fd8affa8840d2d9f7f320201521a702919c677ffFelipe Leme 330009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe LemeTEST_F(DumpstateTest, RunCommandProgress) { 331009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme sp<DumpstateListenerMock> listener(new DumpstateListenerMock()); 332009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme ds.listener_ = listener; 333009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme ds.listener_name_ = "FoxMulder"; 3347447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme SetProgress(0, 30); 33575876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme 336009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme EXPECT_CALL(*listener, onProgressUpdated(20)); 3377447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(20).Build())); 338009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme std::string progress_message = GetProgressMessage(ds.listener_name_, 20, 30); 33975876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme EXPECT_THAT(out, StrEq("stdout\n")); 34075876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme EXPECT_THAT(err, StrEq("stderr\n" + progress_message)); 34175876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme 342009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme EXPECT_CALL(*listener, onProgressUpdated(30)); 3437447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(10).Build())); 344009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme progress_message = GetProgressMessage(ds.listener_name_, 30, 30); 34575876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme EXPECT_THAT(out, StrEq("stdout\n")); 34675876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme EXPECT_THAT(err, StrEq("stderr\n" + progress_message)); 34775876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme 34875876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme // Run a command that will increase maximum timeout. 349009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme EXPECT_CALL(*listener, onProgressUpdated(31)); 350009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme EXPECT_CALL(*listener, onMaxProgressUpdated(37)); 3517447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).Build())); 352009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme progress_message = GetProgressMessage(ds.listener_name_, 31, 37, 30); // 20% increase 35375876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme EXPECT_THAT(out, StrEq("stdout\n")); 35475876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme EXPECT_THAT(err, StrEq("stderr\n" + progress_message)); 35575876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme 35675876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme // Make sure command ran while in dry_run is counted. 35775876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme SetDryRun(true); 358009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme EXPECT_CALL(*listener, onProgressUpdated(35)); 3597447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(4).Build())); 360009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme progress_message = GetProgressMessage(ds.listener_name_, 35, 37); 36175876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme EXPECT_THAT(out, IsEmpty()); 36275876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme EXPECT_THAT(err, StrEq(progress_message)); 363009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme 364009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme ds.listener_.clear(); 36575876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme} 36675876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme 367009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe LemeTEST_F(DumpstateTest, RunCommandProgressIgnoreThreshold) { 36875876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme sp<DumpstateListenerMock> listener(new DumpstateListenerMock()); 36975876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme ds.listener_ = listener; 37075876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme ds.listener_name_ = "FoxMulder"; 371009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme SetProgress(0, 8, 5); // 8 max, 5 threshold 372d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme 373009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme // First update should always be sent. 374009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme EXPECT_CALL(*listener, onProgressUpdated(1)); 375009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).Build())); 376009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme std::string progress_message = GetProgressMessage(ds.listener_name_, 1, 8); 377d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme EXPECT_THAT(out, StrEq("stdout\n")); 3789a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme EXPECT_THAT(err, StrEq("stderr\n" + progress_message)); 379d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme 380009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme // Fourth update should be ignored because it's between the threshold (5 -1 = 4 < 5). 381009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(4).Build())); 382d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme EXPECT_THAT(out, StrEq("stdout\n")); 383009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme EXPECT_THAT(err, StrEq("stderr\n")); 384d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme 385009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme // Third update should be sent because it reaches threshold (6 - 1 = 5). 386009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme EXPECT_CALL(*listener, onProgressUpdated(6)); 3877447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).Build())); 388009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme progress_message = GetProgressMessage(ds.listener_name_, 6, 8); 389d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme EXPECT_THAT(out, StrEq("stdout\n")); 3909a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme EXPECT_THAT(err, StrEq("stderr\n" + progress_message)); 391d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme 392009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme // Fourth update should be ignored because it's between the threshold (9 - 6 = 3 < 5). 393009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme // But max update should be sent. 394009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme EXPECT_CALL(*listener, onMaxProgressUpdated(10)); // 9 * 120% = 10.8 = 10 395009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(3).Build())); 396009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme progress_message = GetProgressMessage(ds.listener_name_, 9, 10, 8, false); 397009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme EXPECT_THAT(out, StrEq("stdout\n")); 398009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme EXPECT_THAT(err, StrEq("stderr\n" + progress_message)); 39975876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme 40075876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme ds.listener_.clear(); 401d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme} 402d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme 403d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe LemeTEST_F(DumpstateTest, RunCommandDropRoot) { 404d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme // First check root case - only available when running with 'adb root'. 405d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme uid_t uid = getuid(); 406d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme if (uid == 0) { 4077447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"})); 408d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme EXPECT_THAT(out, StrEq("0\nstdout\n")); 409d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme EXPECT_THAT(err, StrEq("stderr\n")); 410d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme return; 411d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme } 4127447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme // Then run dropping root. 4137447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"}, 414d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme CommandOptions::WithTimeout(1).DropRoot().Build())); 415d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme EXPECT_THAT(out, StrEq("2000\nstdout\n")); 41626c4157a0823688ba78bf29d93fbce0def3a0fa6Felipe Leme EXPECT_THAT(err, StrEq("drop_root_user(): already running as Shell\nstderr\n")); 417d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme} 418d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme 419d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe LemeTEST_F(DumpstateTest, RunCommandAsRootUserBuild) { 420d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme if (!IsUserBuild()) { 421d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme // Emulates user build if necessarily. 422d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme SetBuildType("user"); 423d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme } 424d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme 425d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme DropRoot(); 426d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme 4277447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).AsRoot().Build())); 428d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme 429d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme // We don't know the exact path of su, so we just check for the 'root ...' commands 430d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme EXPECT_THAT(out, StartsWith("Skipping")); 4317447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_THAT(out, EndsWith("root " + kSimpleCommand + "' on user build.\n")); 432d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme EXPECT_THAT(err, IsEmpty()); 433d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme} 434d80e6b6109c52d57ebba675c1f97fcb2ca1d93c5Felipe Leme 435cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe LemeTEST_F(DumpstateTest, DumpFileNotFoundNoTitle) { 436cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe Leme EXPECT_EQ(-1, DumpFile("", "/I/cant/believe/I/exist")); 437cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe Leme EXPECT_THAT(out, 438cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe Leme StrEq("*** Error dumping /I/cant/believe/I/exist: No such file or directory\n")); 439cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe Leme EXPECT_THAT(err, IsEmpty()); 440cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe Leme} 441cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe Leme 442cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe LemeTEST_F(DumpstateTest, DumpFileNotFoundWithTitle) { 443cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe Leme EXPECT_EQ(-1, DumpFile("Y U NO EXIST?", "/I/cant/believe/I/exist")); 444cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe Leme EXPECT_THAT(err, IsEmpty()); 445cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe Leme // We don't know the exact duration, so we check the prefix and suffix 446cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe Leme EXPECT_THAT(out, StartsWith("*** Error dumping /I/cant/believe/I/exist (Y U NO EXIST?): No " 447cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe Leme "such file or directory\n")); 448cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe Leme EXPECT_THAT(out, EndsWith("s was the duration of 'Y U NO EXIST?' ------\n")); 449cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe Leme} 450cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe Leme 451cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe LemeTEST_F(DumpstateTest, DumpFileSingleLine) { 4527447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt")); 453cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe Leme EXPECT_THAT(err, IsEmpty()); 454cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe Leme EXPECT_THAT(out, StrEq("I AM LINE1\n")); // dumpstate adds missing newline 455cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe Leme} 456cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe Leme 457cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe LemeTEST_F(DumpstateTest, DumpFileSingleLineWithNewLine) { 4587447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line-with-newline.txt")); 459cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe Leme EXPECT_THAT(err, IsEmpty()); 460cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe Leme EXPECT_THAT(out, StrEq("I AM LINE1\n")); 461cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe Leme} 462cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe Leme 463cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe LemeTEST_F(DumpstateTest, DumpFileMultipleLines) { 4647447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(0, DumpFile("", kTestDataPath + "multiple-lines.txt")); 465cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe Leme EXPECT_THAT(err, IsEmpty()); 466cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe Leme EXPECT_THAT(out, StrEq("I AM LINE1\nI AM LINE2\nI AM LINE3\n")); 467cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe Leme} 468cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe Leme 469cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe LemeTEST_F(DumpstateTest, DumpFileMultipleLinesWithNewLine) { 4707447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(0, DumpFile("", kTestDataPath + "multiple-lines-with-newline.txt")); 471cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe Leme EXPECT_THAT(err, IsEmpty()); 472cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe Leme EXPECT_THAT(out, StrEq("I AM LINE1\nI AM LINE2\nI AM LINE3\n")); 473cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe Leme} 474cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe Leme 475cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe LemeTEST_F(DumpstateTest, DumpFileOnDryRunNoTitle) { 476cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe Leme SetDryRun(true); 4777447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt")); 478cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe Leme EXPECT_THAT(err, IsEmpty()); 479cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe Leme EXPECT_THAT(out, IsEmpty()); 480cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe Leme} 481cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe Leme 482cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe LemeTEST_F(DumpstateTest, DumpFileOnDryRun) { 483cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe Leme SetDryRun(true); 4847447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(0, DumpFile("Might as well dump. Dump!", kTestDataPath + "single-line.txt")); 485cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe Leme EXPECT_THAT(err, IsEmpty()); 4867447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_THAT(out, StartsWith("------ Might as well dump. Dump! (" + kTestDataPath + 487cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe Leme "single-line.txt) ------\n\t(skipped on dry run)\n------")); 488cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe Leme EXPECT_THAT(out, EndsWith("s was the duration of 'Might as well dump. Dump!' ------\n")); 489cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe Leme EXPECT_THAT(err, IsEmpty()); 490cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe Leme} 491cef0298e2540e6ad8c2728e6fcc007247c68aac0Felipe Leme 49275876a2c0649b8cde36329ca0a1dc6e349af6493Felipe LemeTEST_F(DumpstateTest, DumpFileUpdateProgress) { 49375876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme sp<DumpstateListenerMock> listener(new DumpstateListenerMock()); 49475876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme ds.listener_ = listener; 49575876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme ds.listener_name_ = "FoxMulder"; 4967447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme SetProgress(0, 30); 49775876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme 49875876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme EXPECT_CALL(*listener, onProgressUpdated(5)); 4997447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt")); 50075876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme 50175876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme std::string progress_message = 50275876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme GetProgressMessage(ds.listener_name_, 5, 30); // TODO: unhardcode WEIGHT_FILE (5)? 50375876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme EXPECT_THAT(err, StrEq(progress_message)); 50475876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme EXPECT_THAT(out, StrEq("I AM LINE1\n")); // dumpstate adds missing newline 50575876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme 50675876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme ds.listener_.clear(); 50775876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme} 50875876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme 5097447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Lemeclass DumpstateServiceTest : public DumpstateBaseTest { 51075876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme public: 51175876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme DumpstateService dss; 51275876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme}; 51375876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme 51475876a2c0649b8cde36329ca0a1dc6e349af6493Felipe LemeTEST_F(DumpstateServiceTest, SetListenerNoName) { 51575876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme sp<DumpstateListenerMock> listener(new DumpstateListenerMock()); 516009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme sp<IDumpstateToken> token; 517009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme EXPECT_TRUE(dss.setListener("", listener, &token).isOk()); 518009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme ASSERT_THAT(token, IsNull()); 51975876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme} 52075876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme 52175876a2c0649b8cde36329ca0a1dc6e349af6493Felipe LemeTEST_F(DumpstateServiceTest, SetListenerNoPointer) { 522009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme sp<IDumpstateToken> token; 523009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme EXPECT_TRUE(dss.setListener("whatever", nullptr, &token).isOk()); 524009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme ASSERT_THAT(token, IsNull()); 52575876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme} 52675876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme 52775876a2c0649b8cde36329ca0a1dc6e349af6493Felipe LemeTEST_F(DumpstateServiceTest, SetListenerTwice) { 52875876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme sp<DumpstateListenerMock> listener(new DumpstateListenerMock()); 529009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme sp<IDumpstateToken> token; 530009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme EXPECT_TRUE(dss.setListener("whatever", listener, &token).isOk()); 531009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme ASSERT_THAT(token, NotNull()); 53275876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme EXPECT_THAT(Dumpstate::GetInstance().listener_name_, StrEq("whatever")); 53375876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme 534009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme token.clear(); 535009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme EXPECT_TRUE(dss.setListener("whatsoever", listener, &token).isOk()); 536009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme ASSERT_THAT(token, IsNull()); 537009ecbbd3fcfd06735b0102f0342fc7e60166d9bFelipe Leme EXPECT_THAT(Dumpstate::GetInstance().listener_name_, StrEq("whatever")); 53875876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme} 5397447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme 5407447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Lemeclass ProgressTest : public DumpstateBaseTest { 5417447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme public: 5427447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme Progress GetInstance(int32_t max, double growth_factor, const std::string& path = "") { 5437447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme return Progress(max, growth_factor, path); 5447447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme } 5457447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme 5467447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme void AssertStats(const std::string& path, int32_t expected_runs, int32_t expected_average) { 5477447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme std::string expected_content = 5487447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme android::base::StringPrintf("%d %d\n", expected_runs, expected_average); 5497447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme std::string actual_content; 5507447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme ASSERT_TRUE(android::base::ReadFileToString(path, &actual_content)) 5517447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme << "could not read statsfrom" << path; 5527447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme ASSERT_THAT(actual_content, StrEq(expected_content)) << "invalid stats on " << path; 5537447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme } 5547447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme}; 5557447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme 5567447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe LemeTEST_F(ProgressTest, SimpleTest) { 5577447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme Progress progress; 5587447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(0, progress.Get()); 5597447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(Progress::kDefaultMax, progress.GetInitialMax()); 5607447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(Progress::kDefaultMax, progress.GetMax()); 5617447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme 5627447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme bool max_increased = progress.Inc(1); 5637447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(1, progress.Get()); 5647447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(Progress::kDefaultMax, progress.GetInitialMax()); 5657447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(Progress::kDefaultMax, progress.GetMax()); 5667447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_FALSE(max_increased); 5677447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme 5687447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme // Ignore negative increase. 5697447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme max_increased = progress.Inc(-1); 5707447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(1, progress.Get()); 5717447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(Progress::kDefaultMax, progress.GetInitialMax()); 5727447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(Progress::kDefaultMax, progress.GetMax()); 5737447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_FALSE(max_increased); 5747447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme} 5757447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme 5767447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe LemeTEST_F(ProgressTest, MaxGrowsInsideNewRange) { 5777447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme Progress progress = GetInstance(10, 1.2); // 20% growth factor 5787447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(0, progress.Get()); 5797447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(10, progress.GetInitialMax()); 5807447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(10, progress.GetMax()); 5817447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme 5827447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme // No increase 5837447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme bool max_increased = progress.Inc(10); 5847447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(10, progress.Get()); 5857447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(10, progress.GetMax()); 5867447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_FALSE(max_increased); 5877447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme 5887447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme // Increase, with new value < max*20% 5897447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme max_increased = progress.Inc(1); 5907447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(11, progress.Get()); 5917447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(13, progress.GetMax()); // 11 average * 20% growth = 13.2 = 13 5927447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_TRUE(max_increased); 5937447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme} 5947447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme 5957447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe LemeTEST_F(ProgressTest, MaxGrowsOutsideNewRange) { 5967447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme Progress progress = GetInstance(10, 1.2); // 20% growth factor 5977447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(0, progress.Get()); 5987447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(10, progress.GetInitialMax()); 5997447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(10, progress.GetMax()); 6007447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme 6017447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme // No increase 6027447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme bool max_increased = progress.Inc(10); 6037447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(10, progress.Get()); 6047447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(10, progress.GetMax()); 6057447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_FALSE(max_increased); 6067447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme 6077447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme // Increase, with new value > max*20% 6087447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme max_increased = progress.Inc(5); 6097447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(15, progress.Get()); 6107447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(18, progress.GetMax()); // 15 average * 20% growth = 18 6117447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_TRUE(max_increased); 6127447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme} 6137447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme 6147447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe LemeTEST_F(ProgressTest, InvalidPath) { 6157447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme Progress progress("/devil/null"); 6167447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(Progress::kDefaultMax, progress.GetMax()); 6177447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme} 6187447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme 6197447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe LemeTEST_F(ProgressTest, EmptyFile) { 6207447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme Progress progress(CopyTextFileFixture("empty-file.txt")); 6217447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(Progress::kDefaultMax, progress.GetMax()); 6227447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme} 6237447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme 6247447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe LemeTEST_F(ProgressTest, InvalidLine1stEntryNAN) { 6257447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme Progress progress(CopyTextFileFixture("stats-invalid-1st-NAN.txt")); 6267447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(Progress::kDefaultMax, progress.GetMax()); 6277447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme} 6287447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme 6297447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe LemeTEST_F(ProgressTest, InvalidLine2ndEntryNAN) { 6307447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme Progress progress(CopyTextFileFixture("stats-invalid-2nd-NAN.txt")); 6317447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(Progress::kDefaultMax, progress.GetMax()); 6327447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme} 6337447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme 6347447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe LemeTEST_F(ProgressTest, InvalidLineBothNAN) { 6357447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme Progress progress(CopyTextFileFixture("stats-invalid-both-NAN.txt")); 6367447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(Progress::kDefaultMax, progress.GetMax()); 6377447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme} 6387447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme 6397447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe LemeTEST_F(ProgressTest, InvalidLine1stEntryNegative) { 6407447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme Progress progress(CopyTextFileFixture("stats-invalid-1st-negative.txt")); 6417447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(Progress::kDefaultMax, progress.GetMax()); 6427447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme} 6437447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme 6447447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe LemeTEST_F(ProgressTest, InvalidLine2ndEntryNegative) { 6457447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme Progress progress(CopyTextFileFixture("stats-invalid-2nd-negative.txt")); 6467447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(Progress::kDefaultMax, progress.GetMax()); 6477447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme} 6487447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme 6497447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe LemeTEST_F(ProgressTest, InvalidLine1stEntryTooBig) { 6507447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme Progress progress(CopyTextFileFixture("stats-invalid-1st-too-big.txt")); 6517447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(Progress::kDefaultMax, progress.GetMax()); 6527447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme} 6537447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme 6547447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe LemeTEST_F(ProgressTest, InvalidLine2ndEntryTooBig) { 6557447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme Progress progress(CopyTextFileFixture("stats-invalid-2nd-too-big.txt")); 6567447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(Progress::kDefaultMax, progress.GetMax()); 6577447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme} 6587447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme 6597447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme// Tests stats are properly saved when the file does not exists. 6607447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe LemeTEST_F(ProgressTest, FirstTime) { 6617447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme std::string path = kTestDataPath + "FirstTime.txt"; 6627447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme android::base::RemoveFileIfExists(path); 6637447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme 6647447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme Progress run1(path); 6657447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(0, run1.Get()); 6667447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(Progress::kDefaultMax, run1.GetInitialMax()); 6677447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(Progress::kDefaultMax, run1.GetMax()); 6687447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme 6697447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme bool max_increased = run1.Inc(20); 6707447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(20, run1.Get()); 6717447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(Progress::kDefaultMax, run1.GetMax()); 6727447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_FALSE(max_increased); 6737447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme 6747447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme run1.Save(); 6757447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme AssertStats(path, 1, 20); 6767447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme} 6777447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme 6787447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme// Tests what happens when the persistent settings contains the average duration of 1 run. 6797447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme// Data on file is 1 run and 109 average. 6807447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe LemeTEST_F(ProgressTest, SecondTime) { 6817447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme std::string path = CopyTextFileFixture("stats-one-run-no-newline.txt"); 6827447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme 6837447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme Progress run1 = GetInstance(-42, 1.2, path); 6847447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(0, run1.Get()); 6857447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(10, run1.GetInitialMax()); 6867447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(10, run1.GetMax()); 6877447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme 6887447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme bool max_increased = run1.Inc(20); 6897447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(20, run1.Get()); 6907447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(24, run1.GetMax()); 6917447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_TRUE(max_increased); 6927447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme 6937447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme // Average now is 2 runs and (10 + 20)/ 2 = 15 6947447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme run1.Save(); 6957447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme AssertStats(path, 2, 15); 6967447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme 6977447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme Progress run2 = GetInstance(-42, 1.2, path); 6987447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(0, run2.Get()); 6997447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(15, run2.GetInitialMax()); 7007447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(15, run2.GetMax()); 7017447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme 7027447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme max_increased = run2.Inc(25); 7037447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(25, run2.Get()); 7047447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(30, run2.GetMax()); 7057447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_TRUE(max_increased); 7067447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme 7077447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme // Average now is 3 runs and (15 * 2 + 25)/ 3 = 18.33 = 18 7087447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme run2.Save(); 7097447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme AssertStats(path, 3, 18); 7107447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme 7117447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme Progress run3 = GetInstance(-42, 1.2, path); 7127447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(0, run3.Get()); 7137447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(18, run3.GetInitialMax()); 7147447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(18, run3.GetMax()); 7157447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme 7167447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme // Make sure average decreases as well 7177447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme max_increased = run3.Inc(5); 7187447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(5, run3.Get()); 7197447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(18, run3.GetMax()); 7207447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_FALSE(max_increased); 7217447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme 7227447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme // Average now is 4 runs and (18 * 3 + 5)/ 4 = 14.75 = 14 7237447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme run3.Save(); 7247447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme AssertStats(path, 4, 14); 7257447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme} 7267447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme 7277447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme// Tests what happens when the persistent settings contains the average duration of 2 runs. 7287447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme// Data on file is 2 runs and 15 average. 7297447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe LemeTEST_F(ProgressTest, ThirdTime) { 7307447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme std::string path = CopyTextFileFixture("stats-two-runs.txt"); 7317447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme AssertStats(path, 2, 15); // Sanity check 7327447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme 7337447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme Progress run1 = GetInstance(-42, 1.2, path); 7347447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(0, run1.Get()); 7357447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(15, run1.GetInitialMax()); 7367447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(15, run1.GetMax()); 7377447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme 7387447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme bool max_increased = run1.Inc(20); 7397447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(20, run1.Get()); 7407447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(24, run1.GetMax()); 7417447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_TRUE(max_increased); 7427447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme 7437447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme // Average now is 3 runs and (15 * 2 + 20)/ 3 = 16.66 = 16 7447447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme run1.Save(); 7457447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme AssertStats(path, 3, 16); 7467447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme} 7477447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme 7487447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme// TODO: RunCommandAsRootNonUserBuild must be the last test because it drops root, which could cause 7497447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme// other tests to fail if they're relyin on the process running as root. 7507447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme// For now this is fine, but eventually it might need to be moved to its own test case / process. 7517447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe LemeTEST_F(DumpstateTest, RunCommandAsRootNonUserBuild) { 7527447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme if (IsUserBuild()) { 7537447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme ALOGI("Skipping RunCommandAsRootNonUserBuild on user builds\n"); 7547447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme return; 7557447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme } 7567447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme 7577447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme DropRoot(); 7587447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme 7597447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"}, 7607447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme CommandOptions::WithTimeout(1).AsRoot().Build())); 7617447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme 7627447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_THAT(out, StrEq("0\nstdout\n")); 7637447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme EXPECT_THAT(err, StrEq("stderr\n")); 7647447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme} 765