| Felipe Leme | 343175a | 2016-08-02 18:57:37 -0700 | [diff] [blame] | 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 | #include "../dumpsys.h" | 
 | 18 |  | 
 | 19 | #include <vector> | 
 | 20 |  | 
 | 21 | #include <gmock/gmock.h> | 
 | 22 | #include <gtest/gtest.h> | 
 | 23 |  | 
 | 24 | #include <android-base/file.h> | 
| Vishnu Nair | 6a40853 | 2017-10-24 09:11:27 -0700 | [diff] [blame] | 25 | #include <serviceutils/PriorityDumper.h> | 
| Felipe Leme | 343175a | 2016-08-02 18:57:37 -0700 | [diff] [blame] | 26 | #include <utils/String16.h> | 
| Steven Moreland | a0f7f2d | 2017-03-09 22:59:32 -0800 | [diff] [blame] | 27 | #include <utils/String8.h> | 
| Felipe Leme | 343175a | 2016-08-02 18:57:37 -0700 | [diff] [blame] | 28 | #include <utils/Vector.h> | 
 | 29 |  | 
 | 30 | using namespace android; | 
 | 31 |  | 
 | 32 | using ::testing::_; | 
 | 33 | using ::testing::Action; | 
 | 34 | using ::testing::ActionInterface; | 
 | 35 | using ::testing::DoAll; | 
 | 36 | using ::testing::Eq; | 
 | 37 | using ::testing::HasSubstr; | 
 | 38 | using ::testing::MakeAction; | 
| Felipe Leme | 5c8a98f | 2017-08-25 13:39:04 -0700 | [diff] [blame] | 39 | using ::testing::Mock; | 
| Felipe Leme | 343175a | 2016-08-02 18:57:37 -0700 | [diff] [blame] | 40 | using ::testing::Not; | 
 | 41 | using ::testing::Return; | 
 | 42 | using ::testing::StrEq; | 
 | 43 | using ::testing::Test; | 
 | 44 | using ::testing::WithArg; | 
 | 45 | using ::testing::internal::CaptureStderr; | 
 | 46 | using ::testing::internal::CaptureStdout; | 
 | 47 | using ::testing::internal::GetCapturedStderr; | 
 | 48 | using ::testing::internal::GetCapturedStdout; | 
 | 49 |  | 
 | 50 | class ServiceManagerMock : public IServiceManager { | 
 | 51 |   public: | 
 | 52 |     MOCK_CONST_METHOD1(getService, sp<IBinder>(const String16&)); | 
 | 53 |     MOCK_CONST_METHOD1(checkService, sp<IBinder>(const String16&)); | 
| Vishnu Nair | f56042d | 2017-09-19 15:25:10 -0700 | [diff] [blame] | 54 |     MOCK_METHOD4(addService, status_t(const String16&, const sp<IBinder>&, bool, int)); | 
 | 55 |     MOCK_METHOD1(listServices, Vector<String16>(int)); | 
| Felipe Leme | 343175a | 2016-08-02 18:57:37 -0700 | [diff] [blame] | 56 |  | 
 | 57 |   protected: | 
 | 58 |     MOCK_METHOD0(onAsBinder, IBinder*()); | 
 | 59 | }; | 
 | 60 |  | 
 | 61 | class BinderMock : public BBinder { | 
 | 62 |   public: | 
 | 63 |     BinderMock() { | 
 | 64 |     } | 
 | 65 |  | 
 | 66 |     MOCK_METHOD2(dump, status_t(int, const Vector<String16>&)); | 
 | 67 | }; | 
 | 68 |  | 
 | 69 | // gmock black magic to provide a WithArg<0>(WriteOnFd(output)) matcher | 
 | 70 | typedef void WriteOnFdFunction(int); | 
 | 71 |  | 
 | 72 | class WriteOnFdAction : public ActionInterface<WriteOnFdFunction> { | 
 | 73 |   public: | 
 | 74 |     explicit WriteOnFdAction(const std::string& output) : output_(output) { | 
 | 75 |     } | 
 | 76 |     virtual Result Perform(const ArgumentTuple& args) { | 
| Haibo Huang | 21f3655 | 2018-07-10 19:48:18 -0700 | [diff] [blame] | 77 |         int fd = ::testing::get<0>(args); | 
| Felipe Leme | 343175a | 2016-08-02 18:57:37 -0700 | [diff] [blame] | 78 |         android::base::WriteStringToFd(output_, fd); | 
 | 79 |     } | 
 | 80 |  | 
 | 81 |   private: | 
 | 82 |     std::string output_; | 
 | 83 | }; | 
 | 84 |  | 
 | 85 | // Matcher used to emulate dump() by writing on its file descriptor. | 
 | 86 | Action<WriteOnFdFunction> WriteOnFd(const std::string& output) { | 
 | 87 |     return MakeAction(new WriteOnFdAction(output)); | 
 | 88 | } | 
 | 89 |  | 
 | 90 | // Matcher for args using Android's Vector<String16> format | 
 | 91 | // TODO: move it to some common testing library | 
 | 92 | MATCHER_P(AndroidElementsAre, expected, "") { | 
 | 93 |     std::ostringstream errors; | 
 | 94 |     if (arg.size() != expected.size()) { | 
 | 95 |         errors << " sizes do not match (expected " << expected.size() << ", got " << arg.size() | 
 | 96 |                << ")\n"; | 
 | 97 |     } | 
 | 98 |     int i = 0; | 
 | 99 |     std::ostringstream actual_stream, expected_stream; | 
| Chih-Hung Hsieh | cb057c2 | 2017-08-03 15:48:25 -0700 | [diff] [blame] | 100 |     for (const String16& actual : arg) { | 
| Steven Moreland | a0f7f2d | 2017-03-09 22:59:32 -0800 | [diff] [blame] | 101 |         std::string actual_str = String8(actual).c_str(); | 
| Felipe Leme | 343175a | 2016-08-02 18:57:37 -0700 | [diff] [blame] | 102 |         std::string expected_str = expected[i]; | 
 | 103 |         actual_stream << "'" << actual_str << "' "; | 
 | 104 |         expected_stream << "'" << expected_str << "' "; | 
 | 105 |         if (actual_str != expected_str) { | 
 | 106 |             errors << " element mismatch at index " << i << "\n"; | 
 | 107 |         } | 
 | 108 |         i++; | 
 | 109 |     } | 
 | 110 |  | 
 | 111 |     if (!errors.str().empty()) { | 
 | 112 |         errors << "\nExpected args: " << expected_stream.str() | 
 | 113 |                << "\nActual args: " << actual_stream.str(); | 
 | 114 |         *result_listener << errors.str(); | 
 | 115 |         return false; | 
 | 116 |     } | 
 | 117 |     return true; | 
 | 118 | } | 
 | 119 |  | 
 | 120 | // Custom action to sleep for timeout seconds | 
 | 121 | ACTION_P(Sleep, timeout) { | 
 | 122 |     sleep(timeout); | 
 | 123 | } | 
 | 124 |  | 
 | 125 | class DumpsysTest : public Test { | 
 | 126 |   public: | 
| Steven Moreland | 2c3cd83 | 2017-02-13 23:44:17 +0000 | [diff] [blame] | 127 |     DumpsysTest() : sm_(), dump_(&sm_), stdout_(), stderr_() { | 
| Felipe Leme | 343175a | 2016-08-02 18:57:37 -0700 | [diff] [blame] | 128 |     } | 
 | 129 |  | 
 | 130 |     void ExpectListServices(std::vector<std::string> services) { | 
 | 131 |         Vector<String16> services16; | 
 | 132 |         for (auto& service : services) { | 
 | 133 |             services16.add(String16(service.c_str())); | 
 | 134 |         } | 
| Vishnu Nair | 6a40853 | 2017-10-24 09:11:27 -0700 | [diff] [blame] | 135 |         EXPECT_CALL(sm_, listServices(IServiceManager::DUMP_FLAG_PRIORITY_ALL)) | 
| Vishnu Nair | f56042d | 2017-09-19 15:25:10 -0700 | [diff] [blame] | 136 |             .WillRepeatedly(Return(services16)); | 
 | 137 |     } | 
 | 138 |  | 
| Vishnu Nair | 6a40853 | 2017-10-24 09:11:27 -0700 | [diff] [blame] | 139 |     void ExpectListServicesWithPriority(std::vector<std::string> services, int dumpFlags) { | 
| Vishnu Nair | f56042d | 2017-09-19 15:25:10 -0700 | [diff] [blame] | 140 |         Vector<String16> services16; | 
 | 141 |         for (auto& service : services) { | 
 | 142 |             services16.add(String16(service.c_str())); | 
 | 143 |         } | 
| Vishnu Nair | 6a40853 | 2017-10-24 09:11:27 -0700 | [diff] [blame] | 144 |         EXPECT_CALL(sm_, listServices(dumpFlags)).WillRepeatedly(Return(services16)); | 
| Felipe Leme | 343175a | 2016-08-02 18:57:37 -0700 | [diff] [blame] | 145 |     } | 
 | 146 |  | 
 | 147 |     sp<BinderMock> ExpectCheckService(const char* name, bool running = true) { | 
 | 148 |         sp<BinderMock> binder_mock; | 
 | 149 |         if (running) { | 
 | 150 |             binder_mock = new BinderMock; | 
 | 151 |         } | 
 | 152 |         EXPECT_CALL(sm_, checkService(String16(name))).WillRepeatedly(Return(binder_mock)); | 
 | 153 |         return binder_mock; | 
 | 154 |     } | 
 | 155 |  | 
 | 156 |     void ExpectDump(const char* name, const std::string& output) { | 
 | 157 |         sp<BinderMock> binder_mock = ExpectCheckService(name); | 
 | 158 |         EXPECT_CALL(*binder_mock, dump(_, _)) | 
 | 159 |             .WillRepeatedly(DoAll(WithArg<0>(WriteOnFd(output)), Return(0))); | 
 | 160 |     } | 
 | 161 |  | 
 | 162 |     void ExpectDumpWithArgs(const char* name, std::vector<std::string> args, | 
 | 163 |                             const std::string& output) { | 
 | 164 |         sp<BinderMock> binder_mock = ExpectCheckService(name); | 
 | 165 |         EXPECT_CALL(*binder_mock, dump(_, AndroidElementsAre(args))) | 
 | 166 |             .WillRepeatedly(DoAll(WithArg<0>(WriteOnFd(output)), Return(0))); | 
 | 167 |     } | 
 | 168 |  | 
| Felipe Leme | 5c8a98f | 2017-08-25 13:39:04 -0700 | [diff] [blame] | 169 |     sp<BinderMock> ExpectDumpAndHang(const char* name, int timeout_s, const std::string& output) { | 
| Felipe Leme | 343175a | 2016-08-02 18:57:37 -0700 | [diff] [blame] | 170 |         sp<BinderMock> binder_mock = ExpectCheckService(name); | 
 | 171 |         EXPECT_CALL(*binder_mock, dump(_, _)) | 
 | 172 |             .WillRepeatedly(DoAll(Sleep(timeout_s), WithArg<0>(WriteOnFd(output)), Return(0))); | 
| Felipe Leme | 5c8a98f | 2017-08-25 13:39:04 -0700 | [diff] [blame] | 173 |         return binder_mock; | 
| Felipe Leme | 343175a | 2016-08-02 18:57:37 -0700 | [diff] [blame] | 174 |     } | 
 | 175 |  | 
 | 176 |     void CallMain(const std::vector<std::string>& args) { | 
 | 177 |         const char* argv[1024] = {"/some/virtual/dir/dumpsys"}; | 
 | 178 |         int argc = (int)args.size() + 1; | 
 | 179 |         int i = 1; | 
 | 180 |         for (const std::string& arg : args) { | 
 | 181 |             argv[i++] = arg.c_str(); | 
 | 182 |         } | 
 | 183 |         CaptureStdout(); | 
 | 184 |         CaptureStderr(); | 
 | 185 |         int status = dump_.main(argc, const_cast<char**>(argv)); | 
 | 186 |         stdout_ = GetCapturedStdout(); | 
 | 187 |         stderr_ = GetCapturedStderr(); | 
 | 188 |         EXPECT_THAT(status, Eq(0)); | 
 | 189 |     } | 
 | 190 |  | 
| Vishnu Nair | e4f6174 | 2017-12-21 08:30:28 -0800 | [diff] [blame] | 191 |     void CallSingleService(const String16& serviceName, Vector<String16>& args, int priorityFlags, | 
 | 192 |                            bool supportsProto, std::chrono::duration<double>& elapsedDuration, | 
 | 193 |                            size_t& bytesWritten) { | 
 | 194 |         CaptureStdout(); | 
 | 195 |         CaptureStderr(); | 
 | 196 |         dump_.setServiceArgs(args, supportsProto, priorityFlags); | 
 | 197 |         status_t status = dump_.startDumpThread(serviceName, args); | 
 | 198 |         EXPECT_THAT(status, Eq(0)); | 
 | 199 |         status = dump_.writeDump(STDOUT_FILENO, serviceName, std::chrono::milliseconds(500), false, | 
 | 200 |                                  elapsedDuration, bytesWritten); | 
 | 201 |         EXPECT_THAT(status, Eq(0)); | 
 | 202 |         dump_.stopDumpThread(/* dumpCompleted = */ true); | 
 | 203 |         stdout_ = GetCapturedStdout(); | 
 | 204 |         stderr_ = GetCapturedStderr(); | 
 | 205 |     } | 
 | 206 |  | 
| Steven Moreland | 2c3cd83 | 2017-02-13 23:44:17 +0000 | [diff] [blame] | 207 |     void AssertRunningServices(const std::vector<std::string>& services) { | 
| Vishnu Nair | f56042d | 2017-09-19 15:25:10 -0700 | [diff] [blame] | 208 |         std::string expected; | 
 | 209 |         if (services.size() > 1) { | 
 | 210 |             expected.append("Currently running services:\n"); | 
 | 211 |         } | 
| Felipe Leme | 343175a | 2016-08-02 18:57:37 -0700 | [diff] [blame] | 212 |         for (const std::string& service : services) { | 
 | 213 |             expected.append("  ").append(service).append("\n"); | 
 | 214 |         } | 
 | 215 |         EXPECT_THAT(stdout_, HasSubstr(expected)); | 
 | 216 |     } | 
 | 217 |  | 
 | 218 |     void AssertOutput(const std::string& expected) { | 
 | 219 |         EXPECT_THAT(stdout_, StrEq(expected)); | 
 | 220 |     } | 
 | 221 |  | 
 | 222 |     void AssertOutputContains(const std::string& expected) { | 
 | 223 |         EXPECT_THAT(stdout_, HasSubstr(expected)); | 
 | 224 |     } | 
 | 225 |  | 
 | 226 |     void AssertDumped(const std::string& service, const std::string& dump) { | 
 | 227 |         EXPECT_THAT(stdout_, HasSubstr("DUMP OF SERVICE " + service + ":\n" + dump)); | 
| Vishnu Nair | e4f6174 | 2017-12-21 08:30:28 -0800 | [diff] [blame] | 228 |         EXPECT_THAT(stdout_, HasSubstr("was the duration of dumpsys " + service + ", ending at: ")); | 
| Felipe Leme | 343175a | 2016-08-02 18:57:37 -0700 | [diff] [blame] | 229 |     } | 
 | 230 |  | 
| Vishnu Nair | 6a40853 | 2017-10-24 09:11:27 -0700 | [diff] [blame] | 231 |     void AssertDumpedWithPriority(const std::string& service, const std::string& dump, | 
 | 232 |                                   const char16_t* priorityType) { | 
 | 233 |         std::string priority = String8(priorityType).c_str(); | 
 | 234 |         EXPECT_THAT(stdout_, | 
 | 235 |                     HasSubstr("DUMP OF SERVICE " + priority + " " + service + ":\n" + dump)); | 
| Vishnu Nair | e4f6174 | 2017-12-21 08:30:28 -0800 | [diff] [blame] | 236 |         EXPECT_THAT(stdout_, HasSubstr("was the duration of dumpsys " + service + ", ending at: ")); | 
| Vishnu Nair | 6a40853 | 2017-10-24 09:11:27 -0700 | [diff] [blame] | 237 |     } | 
 | 238 |  | 
| Felipe Leme | 343175a | 2016-08-02 18:57:37 -0700 | [diff] [blame] | 239 |     void AssertNotDumped(const std::string& dump) { | 
 | 240 |         EXPECT_THAT(stdout_, Not(HasSubstr(dump))); | 
 | 241 |     } | 
 | 242 |  | 
 | 243 |     void AssertStopped(const std::string& service) { | 
 | 244 |         EXPECT_THAT(stderr_, HasSubstr("Can't find service: " + service + "\n")); | 
 | 245 |     } | 
 | 246 |  | 
 | 247 |     ServiceManagerMock sm_; | 
 | 248 |     Dumpsys dump_; | 
 | 249 |  | 
 | 250 |   private: | 
 | 251 |     std::string stdout_, stderr_; | 
 | 252 | }; | 
 | 253 |  | 
| Felipe Leme | 343175a | 2016-08-02 18:57:37 -0700 | [diff] [blame] | 254 | // Tests 'dumpsys -l' when all services are running | 
 | 255 | TEST_F(DumpsysTest, ListAllServices) { | 
 | 256 |     ExpectListServices({"Locksmith", "Valet"}); | 
 | 257 |     ExpectCheckService("Locksmith"); | 
 | 258 |     ExpectCheckService("Valet"); | 
 | 259 |  | 
 | 260 |     CallMain({"-l"}); | 
 | 261 |  | 
 | 262 |     AssertRunningServices({"Locksmith", "Valet"}); | 
 | 263 | } | 
 | 264 |  | 
 | 265 | // Tests 'dumpsys -l' when a service is not running | 
 | 266 | TEST_F(DumpsysTest, ListRunningServices) { | 
 | 267 |     ExpectListServices({"Locksmith", "Valet"}); | 
 | 268 |     ExpectCheckService("Locksmith"); | 
 | 269 |     ExpectCheckService("Valet", false); | 
 | 270 |  | 
 | 271 |     CallMain({"-l"}); | 
 | 272 |  | 
 | 273 |     AssertRunningServices({"Locksmith"}); | 
 | 274 |     AssertNotDumped({"Valet"}); | 
 | 275 | } | 
 | 276 |  | 
| Vishnu Nair | f56042d | 2017-09-19 15:25:10 -0700 | [diff] [blame] | 277 | // Tests 'dumpsys -l --priority HIGH' | 
 | 278 | TEST_F(DumpsysTest, ListAllServicesWithPriority) { | 
| Vishnu Nair | 6a40853 | 2017-10-24 09:11:27 -0700 | [diff] [blame] | 279 |     ExpectListServicesWithPriority({"Locksmith", "Valet"}, IServiceManager::DUMP_FLAG_PRIORITY_HIGH); | 
| Vishnu Nair | f56042d | 2017-09-19 15:25:10 -0700 | [diff] [blame] | 280 |     ExpectCheckService("Locksmith"); | 
 | 281 |     ExpectCheckService("Valet"); | 
 | 282 |  | 
 | 283 |     CallMain({"-l", "--priority", "HIGH"}); | 
 | 284 |  | 
 | 285 |     AssertRunningServices({"Locksmith", "Valet"}); | 
 | 286 | } | 
 | 287 |  | 
 | 288 | // Tests 'dumpsys -l --priority HIGH' with and empty list | 
 | 289 | TEST_F(DumpsysTest, ListEmptyServicesWithPriority) { | 
| Vishnu Nair | 6a40853 | 2017-10-24 09:11:27 -0700 | [diff] [blame] | 290 |     ExpectListServicesWithPriority({}, IServiceManager::DUMP_FLAG_PRIORITY_HIGH); | 
| Vishnu Nair | f56042d | 2017-09-19 15:25:10 -0700 | [diff] [blame] | 291 |  | 
 | 292 |     CallMain({"-l", "--priority", "HIGH"}); | 
 | 293 |  | 
 | 294 |     AssertRunningServices({}); | 
 | 295 | } | 
 | 296 |  | 
| Vishnu Nair | 6a40853 | 2017-10-24 09:11:27 -0700 | [diff] [blame] | 297 | // Tests 'dumpsys -l --proto' | 
 | 298 | TEST_F(DumpsysTest, ListAllServicesWithProto) { | 
 | 299 |     ExpectListServicesWithPriority({"Locksmith", "Valet", "Car"}, | 
 | 300 |                                    IServiceManager::DUMP_FLAG_PRIORITY_ALL); | 
 | 301 |     ExpectListServicesWithPriority({"Valet", "Car"}, IServiceManager::DUMP_FLAG_PROTO); | 
 | 302 |     ExpectCheckService("Car"); | 
 | 303 |     ExpectCheckService("Valet"); | 
 | 304 |  | 
 | 305 |     CallMain({"-l", "--proto"}); | 
 | 306 |  | 
 | 307 |     AssertRunningServices({"Car", "Valet"}); | 
 | 308 | } | 
 | 309 |  | 
| Felipe Leme | 343175a | 2016-08-02 18:57:37 -0700 | [diff] [blame] | 310 | // Tests 'dumpsys service_name' on a service is running | 
 | 311 | TEST_F(DumpsysTest, DumpRunningService) { | 
 | 312 |     ExpectDump("Valet", "Here's your car"); | 
 | 313 |  | 
 | 314 |     CallMain({"Valet"}); | 
 | 315 |  | 
 | 316 |     AssertOutput("Here's your car"); | 
 | 317 | } | 
 | 318 |  | 
 | 319 | // Tests 'dumpsys -t 1 service_name' on a service that times out after 2s | 
| Vishnu Nair | 6921f80 | 2017-11-22 09:17:23 -0800 | [diff] [blame] | 320 | TEST_F(DumpsysTest, DumpRunningServiceTimeoutInSec) { | 
| Felipe Leme | 5c8a98f | 2017-08-25 13:39:04 -0700 | [diff] [blame] | 321 |     sp<BinderMock> binder_mock = ExpectDumpAndHang("Valet", 2, "Here's your car"); | 
| Felipe Leme | 343175a | 2016-08-02 18:57:37 -0700 | [diff] [blame] | 322 |  | 
 | 323 |     CallMain({"-t", "1", "Valet"}); | 
 | 324 |  | 
| Vishnu Nair | 6921f80 | 2017-11-22 09:17:23 -0800 | [diff] [blame] | 325 |     AssertOutputContains("SERVICE 'Valet' DUMP TIMEOUT (1000ms) EXPIRED"); | 
 | 326 |     AssertNotDumped("Here's your car"); | 
 | 327 |  | 
 | 328 |     // TODO(b/65056227): BinderMock is not destructed because thread is detached on dumpsys.cpp | 
 | 329 |     Mock::AllowLeak(binder_mock.get()); | 
 | 330 | } | 
 | 331 |  | 
 | 332 | // Tests 'dumpsys -T 500 service_name' on a service that times out after 2s | 
 | 333 | TEST_F(DumpsysTest, DumpRunningServiceTimeoutInMs) { | 
 | 334 |     sp<BinderMock> binder_mock = ExpectDumpAndHang("Valet", 2, "Here's your car"); | 
 | 335 |  | 
 | 336 |     CallMain({"-T", "500", "Valet"}); | 
 | 337 |  | 
 | 338 |     AssertOutputContains("SERVICE 'Valet' DUMP TIMEOUT (500ms) EXPIRED"); | 
| Felipe Leme | 343175a | 2016-08-02 18:57:37 -0700 | [diff] [blame] | 339 |     AssertNotDumped("Here's your car"); | 
 | 340 |  | 
| Felipe Leme | 5c8a98f | 2017-08-25 13:39:04 -0700 | [diff] [blame] | 341 |     // TODO(b/65056227): BinderMock is not destructed because thread is detached on dumpsys.cpp | 
 | 342 |     Mock::AllowLeak(binder_mock.get()); | 
| Felipe Leme | 343175a | 2016-08-02 18:57:37 -0700 | [diff] [blame] | 343 | } | 
 | 344 |  | 
 | 345 | // Tests 'dumpsys service_name Y U NO HAVE ARGS' on a service that is running | 
 | 346 | TEST_F(DumpsysTest, DumpWithArgsRunningService) { | 
 | 347 |     ExpectDumpWithArgs("SERVICE", {"Y", "U", "NO", "HANDLE", "ARGS"}, "I DO!"); | 
 | 348 |  | 
 | 349 |     CallMain({"SERVICE", "Y", "U", "NO", "HANDLE", "ARGS"}); | 
 | 350 |  | 
 | 351 |     AssertOutput("I DO!"); | 
 | 352 | } | 
 | 353 |  | 
| Vishnu Nair | 64afc02 | 2018-02-01 15:29:34 -0800 | [diff] [blame] | 354 | // Tests dumpsys passes the -a flag when called on all services | 
 | 355 | TEST_F(DumpsysTest, PassAllFlagsToServices) { | 
 | 356 |     ExpectListServices({"Locksmith", "Valet"}); | 
 | 357 |     ExpectCheckService("Locksmith"); | 
 | 358 |     ExpectCheckService("Valet"); | 
 | 359 |     ExpectDumpWithArgs("Locksmith", {"-a"}, "dumped1"); | 
 | 360 |     ExpectDumpWithArgs("Valet", {"-a"}, "dumped2"); | 
 | 361 |  | 
 | 362 |     CallMain({"-T", "500"}); | 
 | 363 |  | 
 | 364 |     AssertDumped("Locksmith", "dumped1"); | 
 | 365 |     AssertDumped("Valet", "dumped2"); | 
 | 366 | } | 
 | 367 |  | 
 | 368 | // Tests dumpsys passes the -a flag when called on NORMAL priority services | 
 | 369 | TEST_F(DumpsysTest, PassAllFlagsToNormalServices) { | 
 | 370 |     ExpectListServicesWithPriority({"Locksmith", "Valet"}, | 
 | 371 |                                    IServiceManager::DUMP_FLAG_PRIORITY_NORMAL); | 
 | 372 |     ExpectCheckService("Locksmith"); | 
 | 373 |     ExpectCheckService("Valet"); | 
| Vishnu Nair | 3919e1c | 2018-05-01 17:01:00 -0700 | [diff] [blame] | 374 |     ExpectDumpWithArgs("Locksmith", {"--dump-priority", "NORMAL", "-a"}, "dump1"); | 
 | 375 |     ExpectDumpWithArgs("Valet", {"--dump-priority", "NORMAL", "-a"}, "dump2"); | 
| Vishnu Nair | 64afc02 | 2018-02-01 15:29:34 -0800 | [diff] [blame] | 376 |  | 
 | 377 |     CallMain({"--priority", "NORMAL"}); | 
 | 378 |  | 
 | 379 |     AssertDumped("Locksmith", "dump1"); | 
 | 380 |     AssertDumped("Valet", "dump2"); | 
 | 381 | } | 
 | 382 |  | 
 | 383 | // Tests dumpsys passes only priority flags when called on CRITICAL priority services | 
 | 384 | TEST_F(DumpsysTest, PassPriorityFlagsToCriticalServices) { | 
 | 385 |     ExpectListServicesWithPriority({"Locksmith", "Valet"}, | 
 | 386 |                                    IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL); | 
 | 387 |     ExpectCheckService("Locksmith"); | 
 | 388 |     ExpectCheckService("Valet"); | 
 | 389 |     ExpectDumpWithArgs("Locksmith", {"--dump-priority", "CRITICAL"}, "dump1"); | 
 | 390 |     ExpectDumpWithArgs("Valet", {"--dump-priority", "CRITICAL"}, "dump2"); | 
 | 391 |  | 
 | 392 |     CallMain({"--priority", "CRITICAL"}); | 
 | 393 |  | 
 | 394 |     AssertDumpedWithPriority("Locksmith", "dump1", PriorityDumper::PRIORITY_ARG_CRITICAL); | 
 | 395 |     AssertDumpedWithPriority("Valet", "dump2", PriorityDumper::PRIORITY_ARG_CRITICAL); | 
 | 396 | } | 
 | 397 |  | 
 | 398 | // Tests dumpsys passes only priority flags when called on HIGH priority services | 
 | 399 | TEST_F(DumpsysTest, PassPriorityFlagsToHighServices) { | 
 | 400 |     ExpectListServicesWithPriority({"Locksmith", "Valet"}, | 
 | 401 |                                    IServiceManager::DUMP_FLAG_PRIORITY_HIGH); | 
 | 402 |     ExpectCheckService("Locksmith"); | 
 | 403 |     ExpectCheckService("Valet"); | 
 | 404 |     ExpectDumpWithArgs("Locksmith", {"--dump-priority", "HIGH"}, "dump1"); | 
 | 405 |     ExpectDumpWithArgs("Valet", {"--dump-priority", "HIGH"}, "dump2"); | 
 | 406 |  | 
 | 407 |     CallMain({"--priority", "HIGH"}); | 
 | 408 |  | 
 | 409 |     AssertDumpedWithPriority("Locksmith", "dump1", PriorityDumper::PRIORITY_ARG_HIGH); | 
 | 410 |     AssertDumpedWithPriority("Valet", "dump2", PriorityDumper::PRIORITY_ARG_HIGH); | 
 | 411 | } | 
 | 412 |  | 
| Felipe Leme | 343175a | 2016-08-02 18:57:37 -0700 | [diff] [blame] | 413 | // Tests 'dumpsys' with no arguments | 
 | 414 | TEST_F(DumpsysTest, DumpMultipleServices) { | 
 | 415 |     ExpectListServices({"running1", "stopped2", "running3"}); | 
 | 416 |     ExpectDump("running1", "dump1"); | 
 | 417 |     ExpectCheckService("stopped2", false); | 
 | 418 |     ExpectDump("running3", "dump3"); | 
 | 419 |  | 
 | 420 |     CallMain({}); | 
 | 421 |  | 
 | 422 |     AssertRunningServices({"running1", "running3"}); | 
 | 423 |     AssertDumped("running1", "dump1"); | 
 | 424 |     AssertStopped("stopped2"); | 
 | 425 |     AssertDumped("running3", "dump3"); | 
 | 426 | } | 
 | 427 |  | 
 | 428 | // Tests 'dumpsys --skip skipped3 skipped5', which should skip these services | 
 | 429 | TEST_F(DumpsysTest, DumpWithSkip) { | 
 | 430 |     ExpectListServices({"running1", "stopped2", "skipped3", "running4", "skipped5"}); | 
 | 431 |     ExpectDump("running1", "dump1"); | 
 | 432 |     ExpectCheckService("stopped2", false); | 
 | 433 |     ExpectDump("skipped3", "dump3"); | 
 | 434 |     ExpectDump("running4", "dump4"); | 
 | 435 |     ExpectDump("skipped5", "dump5"); | 
 | 436 |  | 
 | 437 |     CallMain({"--skip", "skipped3", "skipped5"}); | 
 | 438 |  | 
 | 439 |     AssertRunningServices({"running1", "running4", "skipped3 (skipped)", "skipped5 (skipped)"}); | 
 | 440 |     AssertDumped("running1", "dump1"); | 
 | 441 |     AssertDumped("running4", "dump4"); | 
 | 442 |     AssertStopped("stopped2"); | 
 | 443 |     AssertNotDumped("dump3"); | 
 | 444 |     AssertNotDumped("dump5"); | 
 | 445 | } | 
| Vishnu Nair | f56042d | 2017-09-19 15:25:10 -0700 | [diff] [blame] | 446 |  | 
 | 447 | // Tests 'dumpsys --skip skipped3 skipped5 --priority CRITICAL', which should skip these services | 
 | 448 | TEST_F(DumpsysTest, DumpWithSkipAndPriority) { | 
 | 449 |     ExpectListServicesWithPriority({"running1", "stopped2", "skipped3", "running4", "skipped5"}, | 
| Vishnu Nair | 6a40853 | 2017-10-24 09:11:27 -0700 | [diff] [blame] | 450 |                                    IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL); | 
| Vishnu Nair | f56042d | 2017-09-19 15:25:10 -0700 | [diff] [blame] | 451 |     ExpectDump("running1", "dump1"); | 
 | 452 |     ExpectCheckService("stopped2", false); | 
 | 453 |     ExpectDump("skipped3", "dump3"); | 
 | 454 |     ExpectDump("running4", "dump4"); | 
 | 455 |     ExpectDump("skipped5", "dump5"); | 
 | 456 |  | 
 | 457 |     CallMain({"--priority", "CRITICAL", "--skip", "skipped3", "skipped5"}); | 
 | 458 |  | 
 | 459 |     AssertRunningServices({"running1", "running4", "skipped3 (skipped)", "skipped5 (skipped)"}); | 
| Vishnu Nair | 6a40853 | 2017-10-24 09:11:27 -0700 | [diff] [blame] | 460 |     AssertDumpedWithPriority("running1", "dump1", PriorityDumper::PRIORITY_ARG_CRITICAL); | 
 | 461 |     AssertDumpedWithPriority("running4", "dump4", PriorityDumper::PRIORITY_ARG_CRITICAL); | 
| Vishnu Nair | f56042d | 2017-09-19 15:25:10 -0700 | [diff] [blame] | 462 |     AssertStopped("stopped2"); | 
 | 463 |     AssertNotDumped("dump3"); | 
 | 464 |     AssertNotDumped("dump5"); | 
 | 465 | } | 
 | 466 |  | 
 | 467 | // Tests 'dumpsys --priority CRITICAL' | 
 | 468 | TEST_F(DumpsysTest, DumpWithPriorityCritical) { | 
 | 469 |     ExpectListServicesWithPriority({"runningcritical1", "runningcritical2"}, | 
| Vishnu Nair | 6a40853 | 2017-10-24 09:11:27 -0700 | [diff] [blame] | 470 |                                    IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL); | 
| Vishnu Nair | f56042d | 2017-09-19 15:25:10 -0700 | [diff] [blame] | 471 |     ExpectDump("runningcritical1", "dump1"); | 
 | 472 |     ExpectDump("runningcritical2", "dump2"); | 
 | 473 |  | 
 | 474 |     CallMain({"--priority", "CRITICAL"}); | 
 | 475 |  | 
 | 476 |     AssertRunningServices({"runningcritical1", "runningcritical2"}); | 
| Vishnu Nair | 6a40853 | 2017-10-24 09:11:27 -0700 | [diff] [blame] | 477 |     AssertDumpedWithPriority("runningcritical1", "dump1", PriorityDumper::PRIORITY_ARG_CRITICAL); | 
 | 478 |     AssertDumpedWithPriority("runningcritical2", "dump2", PriorityDumper::PRIORITY_ARG_CRITICAL); | 
| Vishnu Nair | f56042d | 2017-09-19 15:25:10 -0700 | [diff] [blame] | 479 | } | 
 | 480 |  | 
 | 481 | // Tests 'dumpsys --priority HIGH' | 
 | 482 | TEST_F(DumpsysTest, DumpWithPriorityHigh) { | 
 | 483 |     ExpectListServicesWithPriority({"runninghigh1", "runninghigh2"}, | 
| Vishnu Nair | 6a40853 | 2017-10-24 09:11:27 -0700 | [diff] [blame] | 484 |                                    IServiceManager::DUMP_FLAG_PRIORITY_HIGH); | 
| Vishnu Nair | f56042d | 2017-09-19 15:25:10 -0700 | [diff] [blame] | 485 |     ExpectDump("runninghigh1", "dump1"); | 
 | 486 |     ExpectDump("runninghigh2", "dump2"); | 
 | 487 |  | 
 | 488 |     CallMain({"--priority", "HIGH"}); | 
 | 489 |  | 
 | 490 |     AssertRunningServices({"runninghigh1", "runninghigh2"}); | 
| Vishnu Nair | 6a40853 | 2017-10-24 09:11:27 -0700 | [diff] [blame] | 491 |     AssertDumpedWithPriority("runninghigh1", "dump1", PriorityDumper::PRIORITY_ARG_HIGH); | 
 | 492 |     AssertDumpedWithPriority("runninghigh2", "dump2", PriorityDumper::PRIORITY_ARG_HIGH); | 
| Vishnu Nair | f56042d | 2017-09-19 15:25:10 -0700 | [diff] [blame] | 493 | } | 
 | 494 |  | 
 | 495 | // Tests 'dumpsys --priority NORMAL' | 
 | 496 | TEST_F(DumpsysTest, DumpWithPriorityNormal) { | 
 | 497 |     ExpectListServicesWithPriority({"runningnormal1", "runningnormal2"}, | 
| Vishnu Nair | 6a40853 | 2017-10-24 09:11:27 -0700 | [diff] [blame] | 498 |                                    IServiceManager::DUMP_FLAG_PRIORITY_NORMAL); | 
| Vishnu Nair | f56042d | 2017-09-19 15:25:10 -0700 | [diff] [blame] | 499 |     ExpectDump("runningnormal1", "dump1"); | 
 | 500 |     ExpectDump("runningnormal2", "dump2"); | 
 | 501 |  | 
 | 502 |     CallMain({"--priority", "NORMAL"}); | 
 | 503 |  | 
 | 504 |     AssertRunningServices({"runningnormal1", "runningnormal2"}); | 
| Vishnu Nair | e4f6174 | 2017-12-21 08:30:28 -0800 | [diff] [blame] | 505 |     AssertDumped("runningnormal1", "dump1"); | 
 | 506 |     AssertDumped("runningnormal2", "dump2"); | 
| Vishnu Nair | 6a40853 | 2017-10-24 09:11:27 -0700 | [diff] [blame] | 507 | } | 
 | 508 |  | 
 | 509 | // Tests 'dumpsys --proto' | 
 | 510 | TEST_F(DumpsysTest, DumpWithProto) { | 
 | 511 |     ExpectListServicesWithPriority({"run8", "run1", "run2", "run5"}, | 
 | 512 |                                    IServiceManager::DUMP_FLAG_PRIORITY_ALL); | 
 | 513 |     ExpectListServicesWithPriority({"run3", "run2", "run4", "run8"}, | 
 | 514 |                                    IServiceManager::DUMP_FLAG_PROTO); | 
 | 515 |     ExpectDump("run2", "dump1"); | 
 | 516 |     ExpectDump("run8", "dump2"); | 
 | 517 |  | 
 | 518 |     CallMain({"--proto"}); | 
 | 519 |  | 
 | 520 |     AssertRunningServices({"run2", "run8"}); | 
 | 521 |     AssertDumped("run2", "dump1"); | 
 | 522 |     AssertDumped("run8", "dump2"); | 
 | 523 | } | 
 | 524 |  | 
 | 525 | // Tests 'dumpsys --priority HIGH --proto' | 
 | 526 | TEST_F(DumpsysTest, DumpWithPriorityHighAndProto) { | 
 | 527 |     ExpectListServicesWithPriority({"runninghigh1", "runninghigh2"}, | 
 | 528 |                                    IServiceManager::DUMP_FLAG_PRIORITY_HIGH); | 
 | 529 |     ExpectListServicesWithPriority({"runninghigh1", "runninghigh2", "runninghigh3"}, | 
 | 530 |                                    IServiceManager::DUMP_FLAG_PROTO); | 
 | 531 |  | 
 | 532 |     ExpectDump("runninghigh1", "dump1"); | 
 | 533 |     ExpectDump("runninghigh2", "dump2"); | 
 | 534 |  | 
 | 535 |     CallMain({"--priority", "HIGH", "--proto"}); | 
 | 536 |  | 
 | 537 |     AssertRunningServices({"runninghigh1", "runninghigh2"}); | 
 | 538 |     AssertDumpedWithPriority("runninghigh1", "dump1", PriorityDumper::PRIORITY_ARG_HIGH); | 
 | 539 |     AssertDumpedWithPriority("runninghigh2", "dump2", PriorityDumper::PRIORITY_ARG_HIGH); | 
| Vishnu Nair | f56042d | 2017-09-19 15:25:10 -0700 | [diff] [blame] | 540 | } | 
| Vishnu Nair | e4f6174 | 2017-12-21 08:30:28 -0800 | [diff] [blame] | 541 |  | 
 | 542 | TEST_F(DumpsysTest, GetBytesWritten) { | 
 | 543 |     const char* serviceName = "service2"; | 
 | 544 |     const char* dumpContents = "dump1"; | 
 | 545 |     ExpectDump(serviceName, dumpContents); | 
 | 546 |  | 
 | 547 |     String16 service(serviceName); | 
 | 548 |     Vector<String16> args; | 
 | 549 |     std::chrono::duration<double> elapsedDuration; | 
 | 550 |     size_t bytesWritten; | 
 | 551 |  | 
 | 552 |     CallSingleService(service, args, IServiceManager::DUMP_FLAG_PRIORITY_ALL, | 
 | 553 |                       /* as_proto = */ false, elapsedDuration, bytesWritten); | 
 | 554 |  | 
 | 555 |     AssertOutput(dumpContents); | 
 | 556 |     EXPECT_THAT(bytesWritten, Eq(strlen(dumpContents))); | 
 | 557 | } | 
 | 558 |  | 
 | 559 | TEST_F(DumpsysTest, WriteDumpWithoutThreadStart) { | 
 | 560 |     std::chrono::duration<double> elapsedDuration; | 
 | 561 |     size_t bytesWritten; | 
 | 562 |     status_t status = | 
 | 563 |         dump_.writeDump(STDOUT_FILENO, String16("service"), std::chrono::milliseconds(500), | 
 | 564 |                         /* as_proto = */ false, elapsedDuration, bytesWritten); | 
 | 565 |     EXPECT_THAT(status, Eq(INVALID_OPERATION)); | 
 | 566 | } |