blob: 2cb980002a29dd40c64a6e5fc0f2225a4d2f5b65 [file] [log] [blame]
Felipe Leme4c2d6632016-09-28 14:32:00 -07001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Felipe Leme75876a22016-10-27 16:31:27 -070017#define LOG_TAG "dumpstate"
18#include <cutils/log.h>
19
Felipe Lemef0292972016-11-22 13:57:05 -080020#include "DumpstateInternal.h"
Felipe Leme75876a22016-10-27 16:31:27 -070021#include "DumpstateService.h"
22#include "android/os/BnDumpstate.h"
Felipe Leme4c2d6632016-09-28 14:32:00 -070023#include "dumpstate.h"
24
25#include <gmock/gmock.h>
26#include <gtest/gtest.h>
27
Felipe Leme46b85da2016-11-21 17:40:45 -080028#include <fcntl.h>
Felipe Leme4c2d6632016-09-28 14:32:00 -070029#include <libgen.h>
Felipe Lemefd8affa2016-09-30 17:38:57 -070030#include <signal.h>
31#include <sys/types.h>
Felipe Leme4c2d6632016-09-28 14:32:00 -070032#include <unistd.h>
Felipe Lemefd8affa2016-09-30 17:38:57 -070033#include <thread>
Felipe Leme4c2d6632016-09-28 14:32:00 -070034
35#include <android-base/file.h>
Felipe Lemed80e6b62016-10-03 13:08:14 -070036#include <android-base/properties.h>
37#include <android-base/stringprintf.h>
Felipe Lemefd8affa2016-09-30 17:38:57 -070038#include <android-base/strings.h>
Felipe Leme4c2d6632016-09-28 14:32:00 -070039
Felipe Leme47e9be22016-12-21 15:37:07 -080040namespace android {
41namespace os {
42namespace dumpstate {
Felipe Lemed80e6b62016-10-03 13:08:14 -070043
Felipe Leme4c2d6632016-09-28 14:32:00 -070044using ::testing::EndsWith;
Felipe Leme46b85da2016-11-21 17:40:45 -080045using ::testing::HasSubstr;
Felipe Leme009ecbb2016-11-07 10:18:44 -080046using ::testing::IsNull;
Felipe Leme4c2d6632016-09-28 14:32:00 -070047using ::testing::IsEmpty;
Felipe Leme009ecbb2016-11-07 10:18:44 -080048using ::testing::NotNull;
Felipe Leme4c2d6632016-09-28 14:32:00 -070049using ::testing::StrEq;
50using ::testing::StartsWith;
51using ::testing::Test;
52using ::testing::internal::CaptureStderr;
53using ::testing::internal::CaptureStdout;
54using ::testing::internal::GetCapturedStderr;
55using ::testing::internal::GetCapturedStdout;
56
Nandana Dutt3f8c7172018-09-25 12:01:54 +010057#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
58
Felipe Leme75876a22016-10-27 16:31:27 -070059class DumpstateListenerMock : public IDumpstateListener {
60 public:
61 MOCK_METHOD1(onProgressUpdated, binder::Status(int32_t progress));
62 MOCK_METHOD1(onMaxProgressUpdated, binder::Status(int32_t max_progress));
Vishnu Nair20cf5032018-01-05 13:15:49 -080063 MOCK_METHOD4(onSectionComplete, binder::Status(const ::std::string& name, int32_t status,
64 int32_t size, int32_t durationMs));
Felipe Leme75876a22016-10-27 16:31:27 -070065
66 protected:
67 MOCK_METHOD0(onAsBinder, IBinder*());
68};
69
Felipe Leme46b85da2016-11-21 17:40:45 -080070static int calls_;
71
Felipe Leme7447d7c2016-11-03 18:12:22 -070072// Base class for all tests in this file
73class DumpstateBaseTest : public Test {
Felipe Leme46b85da2016-11-21 17:40:45 -080074 public:
75 virtual void SetUp() override {
76 calls_++;
Felipe Lemef0292972016-11-22 13:57:05 -080077 SetDryRun(false);
Felipe Leme46b85da2016-11-21 17:40:45 -080078 }
79
Felipe Lemef0292972016-11-22 13:57:05 -080080 void SetDryRun(bool dry_run) const {
81 PropertiesHelper::dry_run_ = dry_run;
82 }
83
84 void SetBuildType(const std::string& build_type) const {
85 PropertiesHelper::build_type_ = build_type;
86 }
87
Nandana Dutt4b392be2018-11-02 16:17:05 +000088 void SetUnroot(bool unroot) const {
89 PropertiesHelper::unroot_ = unroot;
90 }
91
Felipe Lemef0292972016-11-22 13:57:05 -080092 bool IsStandalone() const {
Felipe Leme46b85da2016-11-21 17:40:45 -080093 return calls_ == 1;
94 }
95
Felipe Lemef0292972016-11-22 13:57:05 -080096 void DropRoot() const {
97 DropRootUser();
Felipe Leme46b85da2016-11-21 17:40:45 -080098 uid_t uid = getuid();
99 ASSERT_EQ(2000, (int)uid);
100 }
101
Felipe Leme7447d7c2016-11-03 18:12:22 -0700102 protected:
103 const std::string kTestPath = dirname(android::base::GetExecutablePath().c_str());
104 const std::string kFixturesPath = kTestPath + "/../dumpstate_test_fixture/";
Felipe Leme7fb8dee2017-08-25 10:15:01 -0700105 const std::string kTestDataPath = kFixturesPath + "tests/testdata/";
Felipe Leme7447d7c2016-11-03 18:12:22 -0700106 const std::string kSimpleCommand = kFixturesPath + "dumpstate_test_fixture";
107 const std::string kEchoCommand = "/system/bin/echo";
108
109 /*
110 * Copies a text file fixture to a temporary file, returning it's path.
111 *
112 * Useful in cases where the test case changes the content of the tile.
113 */
114 std::string CopyTextFileFixture(const std::string& relative_name) {
115 std::string from = kTestDataPath + relative_name;
116 // Not using TemporaryFile because it's deleted at the end, and it's useful to keep it
117 // around for poking when the test fails.
118 std::string to = kTestDataPath + relative_name + ".tmp";
119 ALOGD("CopyTextFileFixture: from %s to %s\n", from.c_str(), to.c_str());
120 android::base::RemoveFileIfExists(to);
121 CopyTextFile(from, to);
122 return to.c_str();
123 }
124
Felipe Leme46b85da2016-11-21 17:40:45 -0800125 // Need functions that returns void to use assertions -
Felipe Leme7447d7c2016-11-03 18:12:22 -0700126 // https://github.com/google/googletest/blob/master/googletest/docs/AdvancedGuide.md#assertion-placement
Felipe Leme46b85da2016-11-21 17:40:45 -0800127 void ReadFileToString(const std::string& path, std::string* content) {
128 ASSERT_TRUE(android::base::ReadFileToString(path, content))
129 << "could not read contents from " << path;
130 }
131 void WriteStringToFile(const std::string& content, const std::string& path) {
132 ASSERT_TRUE(android::base::WriteStringToFile(content, path))
133 << "could not write contents to " << path;
134 }
135
136 private:
Felipe Leme7447d7c2016-11-03 18:12:22 -0700137 void CopyTextFile(const std::string& from, const std::string& to) {
138 std::string content;
Felipe Leme46b85da2016-11-21 17:40:45 -0800139 ReadFileToString(from, &content);
140 WriteStringToFile(content, to);
Felipe Leme7447d7c2016-11-03 18:12:22 -0700141 }
142};
143
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100144class DumpOptionsTest : public Test {
145 public:
146 virtual ~DumpOptionsTest() {
147 }
148 virtual void SetUp() {
149 options_ = Dumpstate::DumpOptions();
150 }
151
152 Dumpstate::DumpOptions options_;
153};
154
155TEST_F(DumpOptionsTest, InitializeNone) {
156 // clang-format off
157 char* argv[] = {
158 const_cast<char*>("dumpstate")
159 };
160 // clang-format on
161
162 Dumpstate::DumpOptions options;
163 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
164
165 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
166 EXPECT_FALSE(options_.do_add_date);
167 EXPECT_FALSE(options_.do_zip_file);
168 EXPECT_EQ("", options_.use_outfile);
169 EXPECT_FALSE(options_.use_socket);
170 EXPECT_FALSE(options_.use_control_socket);
171 EXPECT_FALSE(options_.show_header_only);
172 EXPECT_TRUE(options_.do_vibrate);
173 EXPECT_FALSE(options_.do_fb);
174 EXPECT_FALSE(options_.do_progress_updates);
175 EXPECT_FALSE(options_.is_remote_mode);
176 EXPECT_FALSE(options_.do_broadcast);
177}
178
179TEST_F(DumpOptionsTest, InitializePartial1) {
180 // clang-format off
181 char* argv[] = {
182 const_cast<char*>("dumpstate"),
183 const_cast<char*>("-d"),
184 const_cast<char*>("-z"),
185 const_cast<char*>("-o abc"),
186 const_cast<char*>("-s"),
187 const_cast<char*>("-S"),
188
189 };
190 // clang-format on
191
192 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
193
194 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
195 EXPECT_TRUE(options_.do_add_date);
196 EXPECT_TRUE(options_.do_zip_file);
197 // TODO: Maybe we should trim the filename
198 EXPECT_EQ(" abc", std::string(options_.use_outfile));
199 EXPECT_TRUE(options_.use_socket);
200 EXPECT_TRUE(options_.use_control_socket);
201
202 // Other options retain default values
203 EXPECT_FALSE(options_.show_header_only);
204 EXPECT_TRUE(options_.do_vibrate);
205 EXPECT_FALSE(options_.do_fb);
206 EXPECT_FALSE(options_.do_progress_updates);
207 EXPECT_FALSE(options_.is_remote_mode);
208 EXPECT_FALSE(options_.do_broadcast);
209}
210
211TEST_F(DumpOptionsTest, InitializePartial2) {
212 // clang-format off
213 char* argv[] = {
214 const_cast<char*>("dumpstate"),
215 const_cast<char*>("-v"),
216 const_cast<char*>("-q"),
217 const_cast<char*>("-p"),
218 const_cast<char*>("-P"),
219 const_cast<char*>("-R"),
220 const_cast<char*>("-B"),
221 };
222 // clang-format on
223
224 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
225
226 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
227 EXPECT_TRUE(options_.show_header_only);
228 EXPECT_FALSE(options_.do_vibrate);
229 EXPECT_TRUE(options_.do_fb);
230 EXPECT_TRUE(options_.do_progress_updates);
231 EXPECT_TRUE(options_.is_remote_mode);
232 EXPECT_TRUE(options_.do_broadcast);
233
234 // Other options retain default values
235 EXPECT_FALSE(options_.do_add_date);
236 EXPECT_FALSE(options_.do_zip_file);
237 EXPECT_EQ("", options_.use_outfile);
238 EXPECT_FALSE(options_.use_socket);
239 EXPECT_FALSE(options_.use_control_socket);
240}
241
242TEST_F(DumpOptionsTest, InitializeHelp) {
243 // clang-format off
244 char* argv[] = {
245 const_cast<char*>("dumpstate"),
246 const_cast<char*>("-h")
247 };
248 // clang-format on
249
250 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
251
252 // -h is for help.
253 EXPECT_EQ(status, Dumpstate::RunStatus::HELP);
254}
255
256TEST_F(DumpOptionsTest, InitializeUnknown) {
257 // clang-format off
258 char* argv[] = {
259 const_cast<char*>("dumpstate"),
260 const_cast<char*>("-u") // unknown flag
261 };
262 // clang-format on
263
264 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
265
266 // -u is unknown.
267 EXPECT_EQ(status, Dumpstate::RunStatus::INVALID_INPUT);
268}
269
270TEST_F(DumpOptionsTest, ValidateOptionsNeedOutfile1) {
271 options_.do_zip_file = true;
272 EXPECT_FALSE(options_.ValidateOptions());
273 options_.use_outfile = "a/b/c";
274 EXPECT_TRUE(options_.ValidateOptions());
275}
276
277TEST_F(DumpOptionsTest, ValidateOptionsNeedOutfile2) {
278 options_.do_broadcast = true;
279 EXPECT_FALSE(options_.ValidateOptions());
280 options_.use_outfile = "a/b/c";
281 EXPECT_TRUE(options_.ValidateOptions());
282}
283
284TEST_F(DumpOptionsTest, ValidateOptionsNeedZipfile) {
285 options_.use_control_socket = true;
286 EXPECT_FALSE(options_.ValidateOptions());
287
288 options_.do_zip_file = true;
289 options_.use_outfile = "a/b/c"; // do_zip_file needs outfile
290 EXPECT_TRUE(options_.ValidateOptions());
291}
292
293TEST_F(DumpOptionsTest, ValidateOptionsUpdateProgressNeedsBroadcast) {
294 options_.do_progress_updates = true;
295 options_.use_outfile = "a/b/c"; // do_progress_updates needs outfile
296 EXPECT_FALSE(options_.ValidateOptions());
297
298 options_.do_broadcast = true;
299 EXPECT_TRUE(options_.ValidateOptions());
300}
301
302TEST_F(DumpOptionsTest, ValidateOptionsRemoteMode) {
303 options_.is_remote_mode = true;
304 EXPECT_FALSE(options_.ValidateOptions());
305
306 options_.do_broadcast = true;
307 options_.do_zip_file = true;
308 options_.do_add_date = true;
309 options_.use_outfile = "a/b/c"; // do_broadcast needs outfile
310 EXPECT_TRUE(options_.ValidateOptions());
311}
312
Felipe Leme7447d7c2016-11-03 18:12:22 -0700313class DumpstateTest : public DumpstateBaseTest {
Felipe Leme4c2d6632016-09-28 14:32:00 -0700314 public:
315 void SetUp() {
Felipe Leme46b85da2016-11-21 17:40:45 -0800316 DumpstateBaseTest::SetUp();
Felipe Leme4c2d6632016-09-28 14:32:00 -0700317 SetDryRun(false);
Felipe Lemed80e6b62016-10-03 13:08:14 -0700318 SetBuildType(android::base::GetProperty("ro.build.type", "(unknown)"));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700319 ds.progress_.reset(new Progress());
Felipe Leme009ecbb2016-11-07 10:18:44 -0800320 ds.update_progress_threshold_ = 0;
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100321 ds.options_.reset(new Dumpstate::DumpOptions());
Felipe Leme4c2d6632016-09-28 14:32:00 -0700322 }
323
324 // Runs a command and capture `stdout` and `stderr`.
Felipe Leme9a523ae2016-10-20 15:10:33 -0700325 int RunCommand(const std::string& title, const std::vector<std::string>& full_command,
Felipe Leme4c2d6632016-09-28 14:32:00 -0700326 const CommandOptions& options = CommandOptions::DEFAULT) {
327 CaptureStdout();
328 CaptureStderr();
Felipe Leme9a523ae2016-10-20 15:10:33 -0700329 int status = ds.RunCommand(title, full_command, options);
Felipe Leme4c2d6632016-09-28 14:32:00 -0700330 out = GetCapturedStdout();
331 err = GetCapturedStderr();
332 return status;
333 }
334
Felipe Lemecef02982016-10-03 17:22:22 -0700335 // Dumps a file and capture `stdout` and `stderr`.
336 int DumpFile(const std::string& title, const std::string& path) {
337 CaptureStdout();
338 CaptureStderr();
339 int status = ds.DumpFile(title, path);
340 out = GetCapturedStdout();
341 err = GetCapturedStderr();
342 return status;
343 }
344
Felipe Leme009ecbb2016-11-07 10:18:44 -0800345 void SetProgress(long progress, long initial_max, long threshold = 0) {
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100346 ds.options_->do_progress_updates = true;
Felipe Leme009ecbb2016-11-07 10:18:44 -0800347 ds.update_progress_threshold_ = threshold;
348 ds.last_updated_progress_ = 0;
Felipe Leme7447d7c2016-11-03 18:12:22 -0700349 ds.progress_.reset(new Progress(initial_max, progress, 1.2));
350 }
351
Felipe Leme7447d7c2016-11-03 18:12:22 -0700352 std::string GetProgressMessage(const std::string& listener_name, int progress, int max,
Felipe Leme009ecbb2016-11-07 10:18:44 -0800353 int old_max = 0, bool update_progress = true) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700354 EXPECT_EQ(progress, ds.progress_->Get()) << "invalid progress";
355 EXPECT_EQ(max, ds.progress_->GetMax()) << "invalid max";
Felipe Leme75876a22016-10-27 16:31:27 -0700356
Felipe Leme7447d7c2016-11-03 18:12:22 -0700357 bool max_increased = old_max > 0;
Felipe Leme75876a22016-10-27 16:31:27 -0700358
Felipe Leme009ecbb2016-11-07 10:18:44 -0800359 std::string message = "";
Felipe Leme75876a22016-10-27 16:31:27 -0700360 if (max_increased) {
Felipe Leme009ecbb2016-11-07 10:18:44 -0800361 message =
Felipe Leme7447d7c2016-11-03 18:12:22 -0700362 android::base::StringPrintf("Adjusting max progress from %d to %d\n", old_max, max);
Felipe Leme75876a22016-10-27 16:31:27 -0700363 }
364
Felipe Leme009ecbb2016-11-07 10:18:44 -0800365 if (update_progress) {
366 message += android::base::StringPrintf("Setting progress (%s): %d/%d\n",
367 listener_name.c_str(), progress, max);
368 }
369
370 return message;
Felipe Lemed80e6b62016-10-03 13:08:14 -0700371 }
372
Felipe Leme4c2d6632016-09-28 14:32:00 -0700373 // `stdout` and `stderr` from the last command ran.
374 std::string out, err;
375
Felipe Lemefd8affa2016-09-30 17:38:57 -0700376 Dumpstate& ds = Dumpstate::GetInstance();
Felipe Leme4c2d6632016-09-28 14:32:00 -0700377};
378
379TEST_F(DumpstateTest, RunCommandNoArgs) {
380 EXPECT_EQ(-1, RunCommand("", {}));
381}
382
383TEST_F(DumpstateTest, RunCommandNoTitle) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700384 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700385 EXPECT_THAT(out, StrEq("stdout\n"));
386 EXPECT_THAT(err, StrEq("stderr\n"));
387}
388
389TEST_F(DumpstateTest, RunCommandWithTitle) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700390 EXPECT_EQ(0, RunCommand("I AM GROOT", {kSimpleCommand}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700391 EXPECT_THAT(err, StrEq("stderr\n"));
392 // We don't know the exact duration, so we check the prefix and suffix
Felipe Lemefd8affa2016-09-30 17:38:57 -0700393 EXPECT_THAT(out,
Felipe Leme7447d7c2016-11-03 18:12:22 -0700394 StartsWith("------ I AM GROOT (" + kSimpleCommand + ") ------\nstdout\n------"));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700395 EXPECT_THAT(out, EndsWith("s was the duration of 'I AM GROOT' ------\n"));
396}
397
Felipe Lemefd8affa2016-09-30 17:38:57 -0700398TEST_F(DumpstateTest, RunCommandWithLoggingMessage) {
Felipe Leme4c2d6632016-09-28 14:32:00 -0700399 EXPECT_EQ(
Felipe Leme7447d7c2016-11-03 18:12:22 -0700400 0, RunCommand("", {kSimpleCommand},
Felipe Lemefd8affa2016-09-30 17:38:57 -0700401 CommandOptions::WithTimeout(10).Log("COMMAND, Y U NO LOG FIRST?").Build()));
402 EXPECT_THAT(out, StrEq("stdout\n"));
403 EXPECT_THAT(err, StrEq("COMMAND, Y U NO LOG FIRST?stderr\n"));
404}
405
406TEST_F(DumpstateTest, RunCommandRedirectStderr) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700407 EXPECT_EQ(0, RunCommand("", {kSimpleCommand},
Felipe Lemefd8affa2016-09-30 17:38:57 -0700408 CommandOptions::WithTimeout(10).RedirectStderr().Build()));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700409 EXPECT_THAT(out, IsEmpty());
Felipe Lemefd8affa2016-09-30 17:38:57 -0700410 EXPECT_THAT(err, StrEq("stdout\nstderr\n"));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700411}
412
413TEST_F(DumpstateTest, RunCommandWithOneArg) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700414 EXPECT_EQ(0, RunCommand("", {kEchoCommand, "one"}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700415 EXPECT_THAT(err, IsEmpty());
416 EXPECT_THAT(out, StrEq("one\n"));
417}
418
Felipe Lemefd8affa2016-09-30 17:38:57 -0700419TEST_F(DumpstateTest, RunCommandWithMultipleArgs) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700420 EXPECT_EQ(0, RunCommand("", {kEchoCommand, "one", "is", "the", "loniest", "number"}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700421 EXPECT_THAT(err, IsEmpty());
422 EXPECT_THAT(out, StrEq("one is the loniest number\n"));
423}
424
425TEST_F(DumpstateTest, RunCommandDryRun) {
426 SetDryRun(true);
Felipe Leme7447d7c2016-11-03 18:12:22 -0700427 EXPECT_EQ(0, RunCommand("I AM GROOT", {kSimpleCommand}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700428 // We don't know the exact duration, so we check the prefix and suffix
Felipe Leme7447d7c2016-11-03 18:12:22 -0700429 EXPECT_THAT(out, StartsWith("------ I AM GROOT (" + kSimpleCommand +
Felipe Leme4c2d6632016-09-28 14:32:00 -0700430 ") ------\n\t(skipped on dry run)\n------"));
431 EXPECT_THAT(out, EndsWith("s was the duration of 'I AM GROOT' ------\n"));
432 EXPECT_THAT(err, IsEmpty());
433}
434
435TEST_F(DumpstateTest, RunCommandDryRunNoTitle) {
436 SetDryRun(true);
Felipe Leme7447d7c2016-11-03 18:12:22 -0700437 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700438 EXPECT_THAT(out, IsEmpty());
439 EXPECT_THAT(err, IsEmpty());
440}
441
442TEST_F(DumpstateTest, RunCommandDryRunAlways) {
443 SetDryRun(true);
Felipe Leme7447d7c2016-11-03 18:12:22 -0700444 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(10).Always().Build()));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700445 EXPECT_THAT(out, StrEq("stdout\n"));
446 EXPECT_THAT(err, StrEq("stderr\n"));
447}
448
Felipe Lemefd8affa2016-09-30 17:38:57 -0700449TEST_F(DumpstateTest, RunCommandNotFound) {
450 EXPECT_NE(0, RunCommand("", {"/there/cannot/be/such/command"}));
451 EXPECT_THAT(out, StartsWith("*** command '/there/cannot/be/such/command' failed: exit code"));
452 EXPECT_THAT(err, StartsWith("execvp on command '/there/cannot/be/such/command' failed"));
453}
454
455TEST_F(DumpstateTest, RunCommandFails) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700456 EXPECT_EQ(42, RunCommand("", {kSimpleCommand, "--exit", "42"}));
457 EXPECT_THAT(out, StrEq("stdout\n*** command '" + kSimpleCommand +
Felipe Leme9a523ae2016-10-20 15:10:33 -0700458 " --exit 42' failed: exit code 42\n"));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700459 EXPECT_THAT(err, StrEq("stderr\n*** command '" + kSimpleCommand +
Felipe Leme9a523ae2016-10-20 15:10:33 -0700460 " --exit 42' failed: exit code 42\n"));
Felipe Lemefd8affa2016-09-30 17:38:57 -0700461}
462
463TEST_F(DumpstateTest, RunCommandCrashes) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700464 EXPECT_NE(0, RunCommand("", {kSimpleCommand, "--crash"}));
Felipe Lemefd8affa2016-09-30 17:38:57 -0700465 // We don't know the exit code, so check just the prefix.
466 EXPECT_THAT(
Felipe Leme7447d7c2016-11-03 18:12:22 -0700467 out, StartsWith("stdout\n*** command '" + kSimpleCommand + " --crash' failed: exit code"));
Felipe Lemefd8affa2016-09-30 17:38:57 -0700468 EXPECT_THAT(
Felipe Leme7447d7c2016-11-03 18:12:22 -0700469 err, StartsWith("stderr\n*** command '" + kSimpleCommand + " --crash' failed: exit code"));
Felipe Lemefd8affa2016-09-30 17:38:57 -0700470}
471
472TEST_F(DumpstateTest, RunCommandTimesout) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700473 EXPECT_EQ(-1, RunCommand("", {kSimpleCommand, "--sleep", "2"},
Felipe Lemefd8affa2016-09-30 17:38:57 -0700474 CommandOptions::WithTimeout(1).Build()));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700475 EXPECT_THAT(out, StartsWith("stdout line1\n*** command '" + kSimpleCommand +
Felipe Lemefd8affa2016-09-30 17:38:57 -0700476 " --sleep 2' timed out after 1"));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700477 EXPECT_THAT(err, StartsWith("sleeping for 2s\n*** command '" + kSimpleCommand +
Felipe Lemefd8affa2016-09-30 17:38:57 -0700478 " --sleep 2' timed out after 1"));
479}
480
481TEST_F(DumpstateTest, RunCommandIsKilled) {
482 CaptureStdout();
483 CaptureStderr();
484
485 std::thread t([=]() {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700486 EXPECT_EQ(SIGTERM, ds.RunCommand("", {kSimpleCommand, "--pid", "--sleep", "20"},
Felipe Lemefd8affa2016-09-30 17:38:57 -0700487 CommandOptions::WithTimeout(100).Always().Build()));
488 });
489
490 // Capture pid and pre-sleep output.
491 sleep(1); // Wait a little bit to make sure pid and 1st line were printed.
492 std::string err = GetCapturedStderr();
493 EXPECT_THAT(err, StrEq("sleeping for 20s\n"));
494
495 std::string out = GetCapturedStdout();
496 std::vector<std::string> lines = android::base::Split(out, "\n");
497 ASSERT_EQ(3, (int)lines.size()) << "Invalid lines before sleep: " << out;
498
499 int pid = atoi(lines[0].c_str());
500 EXPECT_THAT(lines[1], StrEq("stdout line1"));
501 EXPECT_THAT(lines[2], IsEmpty()); // \n
502
503 // Then kill the process.
504 CaptureStdout();
505 CaptureStderr();
506 ASSERT_EQ(0, kill(pid, SIGTERM)) << "failed to kill pid " << pid;
507 t.join();
508
509 // Finally, check output after murder.
510 out = GetCapturedStdout();
511 err = GetCapturedStderr();
512
Felipe Leme7447d7c2016-11-03 18:12:22 -0700513 EXPECT_THAT(out, StrEq("*** command '" + kSimpleCommand +
Felipe Lemefd8affa2016-09-30 17:38:57 -0700514 " --pid --sleep 20' failed: killed by signal 15\n"));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700515 EXPECT_THAT(err, StrEq("*** command '" + kSimpleCommand +
Felipe Lemefd8affa2016-09-30 17:38:57 -0700516 " --pid --sleep 20' failed: killed by signal 15\n"));
517}
518
Felipe Leme75876a22016-10-27 16:31:27 -0700519TEST_F(DumpstateTest, RunCommandProgress) {
520 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
521 ds.listener_ = listener;
522 ds.listener_name_ = "FoxMulder";
Felipe Leme7447d7c2016-11-03 18:12:22 -0700523 SetProgress(0, 30);
Felipe Leme75876a22016-10-27 16:31:27 -0700524
525 EXPECT_CALL(*listener, onProgressUpdated(20));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700526 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(20).Build()));
Felipe Leme75876a22016-10-27 16:31:27 -0700527 std::string progress_message = GetProgressMessage(ds.listener_name_, 20, 30);
528 EXPECT_THAT(out, StrEq("stdout\n"));
529 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
530
531 EXPECT_CALL(*listener, onProgressUpdated(30));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700532 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(10).Build()));
Felipe Leme75876a22016-10-27 16:31:27 -0700533 progress_message = GetProgressMessage(ds.listener_name_, 30, 30);
534 EXPECT_THAT(out, StrEq("stdout\n"));
535 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
536
537 // Run a command that will increase maximum timeout.
538 EXPECT_CALL(*listener, onProgressUpdated(31));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700539 EXPECT_CALL(*listener, onMaxProgressUpdated(37));
540 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).Build()));
541 progress_message = GetProgressMessage(ds.listener_name_, 31, 37, 30); // 20% increase
Felipe Leme75876a22016-10-27 16:31:27 -0700542 EXPECT_THAT(out, StrEq("stdout\n"));
543 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
544
545 // Make sure command ran while in dry_run is counted.
546 SetDryRun(true);
547 EXPECT_CALL(*listener, onProgressUpdated(35));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700548 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(4).Build()));
549 progress_message = GetProgressMessage(ds.listener_name_, 35, 37);
Felipe Leme75876a22016-10-27 16:31:27 -0700550 EXPECT_THAT(out, IsEmpty());
551 EXPECT_THAT(err, StrEq(progress_message));
552
553 ds.listener_.clear();
554}
555
Felipe Leme009ecbb2016-11-07 10:18:44 -0800556TEST_F(DumpstateTest, RunCommandProgressIgnoreThreshold) {
557 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
558 ds.listener_ = listener;
559 ds.listener_name_ = "FoxMulder";
560 SetProgress(0, 8, 5); // 8 max, 5 threshold
561
562 // First update should always be sent.
563 EXPECT_CALL(*listener, onProgressUpdated(1));
564 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).Build()));
565 std::string progress_message = GetProgressMessage(ds.listener_name_, 1, 8);
566 EXPECT_THAT(out, StrEq("stdout\n"));
567 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
568
569 // Fourth update should be ignored because it's between the threshold (5 -1 = 4 < 5).
570 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(4).Build()));
571 EXPECT_THAT(out, StrEq("stdout\n"));
572 EXPECT_THAT(err, StrEq("stderr\n"));
573
574 // Third update should be sent because it reaches threshold (6 - 1 = 5).
575 EXPECT_CALL(*listener, onProgressUpdated(6));
576 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).Build()));
577 progress_message = GetProgressMessage(ds.listener_name_, 6, 8);
578 EXPECT_THAT(out, StrEq("stdout\n"));
579 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
580
581 // Fourth update should be ignored because it's between the threshold (9 - 6 = 3 < 5).
582 // But max update should be sent.
583 EXPECT_CALL(*listener, onMaxProgressUpdated(10)); // 9 * 120% = 10.8 = 10
584 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(3).Build()));
585 progress_message = GetProgressMessage(ds.listener_name_, 9, 10, 8, false);
586 EXPECT_THAT(out, StrEq("stdout\n"));
587 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
588
589 ds.listener_.clear();
590}
591
Felipe Lemed80e6b62016-10-03 13:08:14 -0700592TEST_F(DumpstateTest, RunCommandDropRoot) {
Felipe Leme46b85da2016-11-21 17:40:45 -0800593 if (!IsStandalone()) {
594 // TODO: temporarily disabled because it might cause other tests to fail after dropping
595 // to Shell - need to refactor tests to avoid this problem)
596 MYLOGE("Skipping DumpstateTest.RunCommandDropRoot() on test suite\n")
597 return;
598 }
Felipe Lemed80e6b62016-10-03 13:08:14 -0700599 // First check root case - only available when running with 'adb root'.
600 uid_t uid = getuid();
601 if (uid == 0) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700602 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"}));
Felipe Lemed80e6b62016-10-03 13:08:14 -0700603 EXPECT_THAT(out, StrEq("0\nstdout\n"));
604 EXPECT_THAT(err, StrEq("stderr\n"));
605 return;
606 }
Felipe Leme7447d7c2016-11-03 18:12:22 -0700607 // Then run dropping root.
608 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
Felipe Lemed80e6b62016-10-03 13:08:14 -0700609 CommandOptions::WithTimeout(1).DropRoot().Build()));
610 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
Felipe Leme26c41572016-10-06 14:34:43 -0700611 EXPECT_THAT(err, StrEq("drop_root_user(): already running as Shell\nstderr\n"));
Felipe Lemed80e6b62016-10-03 13:08:14 -0700612}
613
614TEST_F(DumpstateTest, RunCommandAsRootUserBuild) {
Felipe Leme46b85da2016-11-21 17:40:45 -0800615 if (!IsStandalone()) {
616 // TODO: temporarily disabled because it might cause other tests to fail after dropping
617 // to Shell - need to refactor tests to avoid this problem)
618 MYLOGE("Skipping DumpstateTest.RunCommandAsRootUserBuild() on test suite\n")
619 return;
620 }
Felipe Lemef0292972016-11-22 13:57:05 -0800621 if (!PropertiesHelper::IsUserBuild()) {
Felipe Lemed80e6b62016-10-03 13:08:14 -0700622 // Emulates user build if necessarily.
623 SetBuildType("user");
624 }
625
626 DropRoot();
627
Felipe Leme7447d7c2016-11-03 18:12:22 -0700628 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).AsRoot().Build()));
Felipe Lemed80e6b62016-10-03 13:08:14 -0700629
630 // We don't know the exact path of su, so we just check for the 'root ...' commands
631 EXPECT_THAT(out, StartsWith("Skipping"));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700632 EXPECT_THAT(out, EndsWith("root " + kSimpleCommand + "' on user build.\n"));
Felipe Lemed80e6b62016-10-03 13:08:14 -0700633 EXPECT_THAT(err, IsEmpty());
634}
635
Felipe Leme46b85da2016-11-21 17:40:45 -0800636TEST_F(DumpstateTest, RunCommandAsRootNonUserBuild) {
637 if (!IsStandalone()) {
638 // TODO: temporarily disabled because it might cause other tests to fail after dropping
639 // to Shell - need to refactor tests to avoid this problem)
640 MYLOGE("Skipping DumpstateTest.RunCommandAsRootNonUserBuild() on test suite\n")
641 return;
642 }
Felipe Lemef0292972016-11-22 13:57:05 -0800643 if (PropertiesHelper::IsUserBuild()) {
Felipe Leme46b85da2016-11-21 17:40:45 -0800644 ALOGI("Skipping RunCommandAsRootNonUserBuild on user builds\n");
645 return;
646 }
647
648 DropRoot();
649
650 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
651 CommandOptions::WithTimeout(1).AsRoot().Build()));
652
653 EXPECT_THAT(out, StrEq("0\nstdout\n"));
654 EXPECT_THAT(err, StrEq("stderr\n"));
655}
656
Nandana Dutt4b392be2018-11-02 16:17:05 +0000657TEST_F(DumpstateTest, RunCommandAsRootNonUserBuild_withUnroot) {
658 if (!IsStandalone()) {
659 // TODO: temporarily disabled because it might cause other tests to fail after dropping
660 // to Shell - need to refactor tests to avoid this problem)
661 MYLOGE(
662 "Skipping DumpstateTest.RunCommandAsRootNonUserBuild_withUnroot() "
663 "on test suite\n")
664 return;
665 }
666 if (PropertiesHelper::IsUserBuild()) {
667 ALOGI("Skipping RunCommandAsRootNonUserBuild_withUnroot on user builds\n");
668 return;
669 }
670
671 // Same test as above, but with unroot property set, which will override su availability.
672 SetUnroot(true);
673 DropRoot();
674
675 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
676 CommandOptions::WithTimeout(1).AsRoot().Build()));
677
678 // AsRoot is ineffective.
679 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
680 EXPECT_THAT(err, StrEq("drop_root_user(): already running as Shell\nstderr\n"));
681}
682
Yifan Hong48e83a12017-10-03 14:10:07 -0700683TEST_F(DumpstateTest, RunCommandAsRootIfAvailableOnUserBuild) {
684 if (!IsStandalone()) {
685 // TODO: temporarily disabled because it might cause other tests to fail after dropping
686 // to Shell - need to refactor tests to avoid this problem)
687 MYLOGE("Skipping DumpstateTest.RunCommandAsRootIfAvailableOnUserBuild() on test suite\n")
688 return;
689 }
690 if (!PropertiesHelper::IsUserBuild()) {
691 // Emulates user build if necessarily.
692 SetBuildType("user");
693 }
694
695 DropRoot();
696
697 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
698 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
699
700 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
701 EXPECT_THAT(err, StrEq("stderr\n"));
702}
703
704TEST_F(DumpstateTest, RunCommandAsRootIfAvailableOnDebugBuild) {
705 if (!IsStandalone()) {
706 // TODO: temporarily disabled because it might cause other tests to fail after dropping
707 // to Shell - need to refactor tests to avoid this problem)
708 MYLOGE("Skipping DumpstateTest.RunCommandAsRootIfAvailableOnDebugBuild() on test suite\n")
709 return;
710 }
711 if (PropertiesHelper::IsUserBuild()) {
712 ALOGI("Skipping RunCommandAsRootNonUserBuild on user builds\n");
713 return;
714 }
715
716 DropRoot();
717
718 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
719 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
720
721 EXPECT_THAT(out, StrEq("0\nstdout\n"));
722 EXPECT_THAT(err, StrEq("stderr\n"));
723}
724
Nandana Dutt4b392be2018-11-02 16:17:05 +0000725TEST_F(DumpstateTest, RunCommandAsRootIfAvailableOnDebugBuild_withUnroot) {
726 if (!IsStandalone()) {
727 // TODO: temporarily disabled because it might cause other tests to fail after dropping
728 // to Shell - need to refactor tests to avoid this problem)
729 MYLOGE(
730 "Skipping DumpstateTest.RunCommandAsRootIfAvailableOnDebugBuild_withUnroot() "
731 "on test suite\n")
732 return;
733 }
734 if (PropertiesHelper::IsUserBuild()) {
735 ALOGI("Skipping RunCommandAsRootIfAvailableOnDebugBuild_withUnroot on user builds\n");
736 return;
737 }
738 // Same test as above, but with unroot property set, which will override su availability.
739 SetUnroot(true);
740
741 DropRoot();
742
743 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
744 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
745
746 // It's a userdebug build, so "su root" should be available, but unroot=true overrides it.
747 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
748 EXPECT_THAT(err, StrEq("stderr\n"));
749}
750
Felipe Lemecef02982016-10-03 17:22:22 -0700751TEST_F(DumpstateTest, DumpFileNotFoundNoTitle) {
752 EXPECT_EQ(-1, DumpFile("", "/I/cant/believe/I/exist"));
753 EXPECT_THAT(out,
754 StrEq("*** Error dumping /I/cant/believe/I/exist: No such file or directory\n"));
755 EXPECT_THAT(err, IsEmpty());
756}
757
758TEST_F(DumpstateTest, DumpFileNotFoundWithTitle) {
759 EXPECT_EQ(-1, DumpFile("Y U NO EXIST?", "/I/cant/believe/I/exist"));
760 EXPECT_THAT(err, IsEmpty());
761 // We don't know the exact duration, so we check the prefix and suffix
762 EXPECT_THAT(out, StartsWith("*** Error dumping /I/cant/believe/I/exist (Y U NO EXIST?): No "
763 "such file or directory\n"));
764 EXPECT_THAT(out, EndsWith("s was the duration of 'Y U NO EXIST?' ------\n"));
765}
766
767TEST_F(DumpstateTest, DumpFileSingleLine) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700768 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -0700769 EXPECT_THAT(err, IsEmpty());
770 EXPECT_THAT(out, StrEq("I AM LINE1\n")); // dumpstate adds missing newline
771}
772
773TEST_F(DumpstateTest, DumpFileSingleLineWithNewLine) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700774 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line-with-newline.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -0700775 EXPECT_THAT(err, IsEmpty());
776 EXPECT_THAT(out, StrEq("I AM LINE1\n"));
777}
778
779TEST_F(DumpstateTest, DumpFileMultipleLines) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700780 EXPECT_EQ(0, DumpFile("", kTestDataPath + "multiple-lines.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -0700781 EXPECT_THAT(err, IsEmpty());
782 EXPECT_THAT(out, StrEq("I AM LINE1\nI AM LINE2\nI AM LINE3\n"));
783}
784
785TEST_F(DumpstateTest, DumpFileMultipleLinesWithNewLine) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700786 EXPECT_EQ(0, DumpFile("", kTestDataPath + "multiple-lines-with-newline.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -0700787 EXPECT_THAT(err, IsEmpty());
788 EXPECT_THAT(out, StrEq("I AM LINE1\nI AM LINE2\nI AM LINE3\n"));
789}
790
791TEST_F(DumpstateTest, DumpFileOnDryRunNoTitle) {
792 SetDryRun(true);
Felipe Leme7447d7c2016-11-03 18:12:22 -0700793 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -0700794 EXPECT_THAT(err, IsEmpty());
795 EXPECT_THAT(out, IsEmpty());
796}
797
798TEST_F(DumpstateTest, DumpFileOnDryRun) {
799 SetDryRun(true);
Felipe Leme7447d7c2016-11-03 18:12:22 -0700800 EXPECT_EQ(0, DumpFile("Might as well dump. Dump!", kTestDataPath + "single-line.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -0700801 EXPECT_THAT(err, IsEmpty());
Felipe Leme46b85da2016-11-21 17:40:45 -0800802 EXPECT_THAT(
803 out, StartsWith("------ Might as well dump. Dump! (" + kTestDataPath + "single-line.txt:"));
804 EXPECT_THAT(out, HasSubstr("\n\t(skipped on dry run)\n------"));
Felipe Lemecef02982016-10-03 17:22:22 -0700805 EXPECT_THAT(out, EndsWith("s was the duration of 'Might as well dump. Dump!' ------\n"));
Felipe Lemecef02982016-10-03 17:22:22 -0700806}
807
Felipe Leme75876a22016-10-27 16:31:27 -0700808TEST_F(DumpstateTest, DumpFileUpdateProgress) {
809 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
810 ds.listener_ = listener;
811 ds.listener_name_ = "FoxMulder";
Felipe Leme7447d7c2016-11-03 18:12:22 -0700812 SetProgress(0, 30);
Felipe Leme75876a22016-10-27 16:31:27 -0700813
814 EXPECT_CALL(*listener, onProgressUpdated(5));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700815 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
Felipe Leme75876a22016-10-27 16:31:27 -0700816
817 std::string progress_message =
818 GetProgressMessage(ds.listener_name_, 5, 30); // TODO: unhardcode WEIGHT_FILE (5)?
819 EXPECT_THAT(err, StrEq(progress_message));
820 EXPECT_THAT(out, StrEq("I AM LINE1\n")); // dumpstate adds missing newline
821
822 ds.listener_.clear();
823}
824
Felipe Leme7447d7c2016-11-03 18:12:22 -0700825class DumpstateServiceTest : public DumpstateBaseTest {
Felipe Leme75876a22016-10-27 16:31:27 -0700826 public:
827 DumpstateService dss;
828};
829
830TEST_F(DumpstateServiceTest, SetListenerNoName) {
831 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
Felipe Leme009ecbb2016-11-07 10:18:44 -0800832 sp<IDumpstateToken> token;
Vishnu Nair20cf5032018-01-05 13:15:49 -0800833 EXPECT_TRUE(dss.setListener("", listener, /* getSectionDetails = */ false, &token).isOk());
Felipe Leme009ecbb2016-11-07 10:18:44 -0800834 ASSERT_THAT(token, IsNull());
Felipe Leme75876a22016-10-27 16:31:27 -0700835}
836
837TEST_F(DumpstateServiceTest, SetListenerNoPointer) {
Felipe Leme009ecbb2016-11-07 10:18:44 -0800838 sp<IDumpstateToken> token;
Vishnu Nair20cf5032018-01-05 13:15:49 -0800839 EXPECT_TRUE(
840 dss.setListener("whatever", nullptr, /* getSectionDetails = */ false, &token).isOk());
Felipe Leme009ecbb2016-11-07 10:18:44 -0800841 ASSERT_THAT(token, IsNull());
Felipe Leme75876a22016-10-27 16:31:27 -0700842}
843
844TEST_F(DumpstateServiceTest, SetListenerTwice) {
845 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
Felipe Leme009ecbb2016-11-07 10:18:44 -0800846 sp<IDumpstateToken> token;
Vishnu Nair20cf5032018-01-05 13:15:49 -0800847 EXPECT_TRUE(
848 dss.setListener("whatever", listener, /* getSectionDetails = */ false, &token).isOk());
Felipe Leme009ecbb2016-11-07 10:18:44 -0800849 ASSERT_THAT(token, NotNull());
Felipe Leme75876a22016-10-27 16:31:27 -0700850 EXPECT_THAT(Dumpstate::GetInstance().listener_name_, StrEq("whatever"));
Vishnu Nair20cf5032018-01-05 13:15:49 -0800851 EXPECT_FALSE(Dumpstate::GetInstance().report_section_);
Felipe Leme75876a22016-10-27 16:31:27 -0700852
Felipe Leme009ecbb2016-11-07 10:18:44 -0800853 token.clear();
Vishnu Nair20cf5032018-01-05 13:15:49 -0800854 EXPECT_TRUE(
855 dss.setListener("whatsoever", listener, /* getSectionDetails = */ false, &token).isOk());
Felipe Leme009ecbb2016-11-07 10:18:44 -0800856 ASSERT_THAT(token, IsNull());
857 EXPECT_THAT(Dumpstate::GetInstance().listener_name_, StrEq("whatever"));
Vishnu Nair20cf5032018-01-05 13:15:49 -0800858 EXPECT_FALSE(Dumpstate::GetInstance().report_section_);
859}
860
861TEST_F(DumpstateServiceTest, SetListenerWithSectionDetails) {
862 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
863 sp<IDumpstateToken> token;
864 Dumpstate::GetInstance().listener_ = nullptr;
865 EXPECT_TRUE(
866 dss.setListener("whatever", listener, /* getSectionDetails = */ true, &token).isOk());
867 ASSERT_THAT(token, NotNull());
868 EXPECT_THAT(Dumpstate::GetInstance().listener_name_, StrEq("whatever"));
869 EXPECT_TRUE(Dumpstate::GetInstance().report_section_);
Felipe Leme75876a22016-10-27 16:31:27 -0700870}
Felipe Leme7447d7c2016-11-03 18:12:22 -0700871
872class ProgressTest : public DumpstateBaseTest {
873 public:
874 Progress GetInstance(int32_t max, double growth_factor, const std::string& path = "") {
875 return Progress(max, growth_factor, path);
876 }
877
878 void AssertStats(const std::string& path, int32_t expected_runs, int32_t expected_average) {
879 std::string expected_content =
880 android::base::StringPrintf("%d %d\n", expected_runs, expected_average);
881 std::string actual_content;
Felipe Leme46b85da2016-11-21 17:40:45 -0800882 ReadFileToString(path, &actual_content);
Felipe Leme7447d7c2016-11-03 18:12:22 -0700883 ASSERT_THAT(actual_content, StrEq(expected_content)) << "invalid stats on " << path;
884 }
885};
886
887TEST_F(ProgressTest, SimpleTest) {
888 Progress progress;
889 EXPECT_EQ(0, progress.Get());
890 EXPECT_EQ(Progress::kDefaultMax, progress.GetInitialMax());
891 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
892
893 bool max_increased = progress.Inc(1);
894 EXPECT_EQ(1, progress.Get());
895 EXPECT_EQ(Progress::kDefaultMax, progress.GetInitialMax());
896 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
897 EXPECT_FALSE(max_increased);
898
899 // Ignore negative increase.
900 max_increased = progress.Inc(-1);
901 EXPECT_EQ(1, progress.Get());
902 EXPECT_EQ(Progress::kDefaultMax, progress.GetInitialMax());
903 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
904 EXPECT_FALSE(max_increased);
905}
906
907TEST_F(ProgressTest, MaxGrowsInsideNewRange) {
908 Progress progress = GetInstance(10, 1.2); // 20% growth factor
909 EXPECT_EQ(0, progress.Get());
910 EXPECT_EQ(10, progress.GetInitialMax());
911 EXPECT_EQ(10, progress.GetMax());
912
913 // No increase
914 bool max_increased = progress.Inc(10);
915 EXPECT_EQ(10, progress.Get());
916 EXPECT_EQ(10, progress.GetMax());
917 EXPECT_FALSE(max_increased);
918
919 // Increase, with new value < max*20%
920 max_increased = progress.Inc(1);
921 EXPECT_EQ(11, progress.Get());
922 EXPECT_EQ(13, progress.GetMax()); // 11 average * 20% growth = 13.2 = 13
923 EXPECT_TRUE(max_increased);
924}
925
926TEST_F(ProgressTest, MaxGrowsOutsideNewRange) {
927 Progress progress = GetInstance(10, 1.2); // 20% growth factor
928 EXPECT_EQ(0, progress.Get());
929 EXPECT_EQ(10, progress.GetInitialMax());
930 EXPECT_EQ(10, progress.GetMax());
931
932 // No increase
933 bool max_increased = progress.Inc(10);
934 EXPECT_EQ(10, progress.Get());
935 EXPECT_EQ(10, progress.GetMax());
936 EXPECT_FALSE(max_increased);
937
938 // Increase, with new value > max*20%
939 max_increased = progress.Inc(5);
940 EXPECT_EQ(15, progress.Get());
941 EXPECT_EQ(18, progress.GetMax()); // 15 average * 20% growth = 18
942 EXPECT_TRUE(max_increased);
943}
944
945TEST_F(ProgressTest, InvalidPath) {
946 Progress progress("/devil/null");
947 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
948}
949
950TEST_F(ProgressTest, EmptyFile) {
951 Progress progress(CopyTextFileFixture("empty-file.txt"));
952 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
953}
954
955TEST_F(ProgressTest, InvalidLine1stEntryNAN) {
956 Progress progress(CopyTextFileFixture("stats-invalid-1st-NAN.txt"));
957 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
958}
959
960TEST_F(ProgressTest, InvalidLine2ndEntryNAN) {
961 Progress progress(CopyTextFileFixture("stats-invalid-2nd-NAN.txt"));
962 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
963}
964
965TEST_F(ProgressTest, InvalidLineBothNAN) {
966 Progress progress(CopyTextFileFixture("stats-invalid-both-NAN.txt"));
967 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
968}
969
970TEST_F(ProgressTest, InvalidLine1stEntryNegative) {
971 Progress progress(CopyTextFileFixture("stats-invalid-1st-negative.txt"));
972 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
973}
974
975TEST_F(ProgressTest, InvalidLine2ndEntryNegative) {
976 Progress progress(CopyTextFileFixture("stats-invalid-2nd-negative.txt"));
977 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
978}
979
980TEST_F(ProgressTest, InvalidLine1stEntryTooBig) {
981 Progress progress(CopyTextFileFixture("stats-invalid-1st-too-big.txt"));
982 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
983}
984
985TEST_F(ProgressTest, InvalidLine2ndEntryTooBig) {
986 Progress progress(CopyTextFileFixture("stats-invalid-2nd-too-big.txt"));
987 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
988}
989
990// Tests stats are properly saved when the file does not exists.
991TEST_F(ProgressTest, FirstTime) {
Felipe Leme46b85da2016-11-21 17:40:45 -0800992 if (!IsStandalone()) {
993 // TODO: temporarily disabled because it's failing when running as suite
994 MYLOGE("Skipping ProgressTest.FirstTime() on test suite\n")
995 return;
996 }
997
Felipe Leme7447d7c2016-11-03 18:12:22 -0700998 std::string path = kTestDataPath + "FirstTime.txt";
999 android::base::RemoveFileIfExists(path);
1000
1001 Progress run1(path);
1002 EXPECT_EQ(0, run1.Get());
1003 EXPECT_EQ(Progress::kDefaultMax, run1.GetInitialMax());
1004 EXPECT_EQ(Progress::kDefaultMax, run1.GetMax());
1005
1006 bool max_increased = run1.Inc(20);
1007 EXPECT_EQ(20, run1.Get());
1008 EXPECT_EQ(Progress::kDefaultMax, run1.GetMax());
1009 EXPECT_FALSE(max_increased);
1010
1011 run1.Save();
1012 AssertStats(path, 1, 20);
1013}
1014
1015// Tests what happens when the persistent settings contains the average duration of 1 run.
1016// Data on file is 1 run and 109 average.
1017TEST_F(ProgressTest, SecondTime) {
1018 std::string path = CopyTextFileFixture("stats-one-run-no-newline.txt");
1019
1020 Progress run1 = GetInstance(-42, 1.2, path);
1021 EXPECT_EQ(0, run1.Get());
1022 EXPECT_EQ(10, run1.GetInitialMax());
1023 EXPECT_EQ(10, run1.GetMax());
1024
1025 bool max_increased = run1.Inc(20);
1026 EXPECT_EQ(20, run1.Get());
1027 EXPECT_EQ(24, run1.GetMax());
1028 EXPECT_TRUE(max_increased);
1029
1030 // Average now is 2 runs and (10 + 20)/ 2 = 15
1031 run1.Save();
1032 AssertStats(path, 2, 15);
1033
1034 Progress run2 = GetInstance(-42, 1.2, path);
1035 EXPECT_EQ(0, run2.Get());
1036 EXPECT_EQ(15, run2.GetInitialMax());
1037 EXPECT_EQ(15, run2.GetMax());
1038
1039 max_increased = run2.Inc(25);
1040 EXPECT_EQ(25, run2.Get());
1041 EXPECT_EQ(30, run2.GetMax());
1042 EXPECT_TRUE(max_increased);
1043
1044 // Average now is 3 runs and (15 * 2 + 25)/ 3 = 18.33 = 18
1045 run2.Save();
1046 AssertStats(path, 3, 18);
1047
1048 Progress run3 = GetInstance(-42, 1.2, path);
1049 EXPECT_EQ(0, run3.Get());
1050 EXPECT_EQ(18, run3.GetInitialMax());
1051 EXPECT_EQ(18, run3.GetMax());
1052
1053 // Make sure average decreases as well
1054 max_increased = run3.Inc(5);
1055 EXPECT_EQ(5, run3.Get());
1056 EXPECT_EQ(18, run3.GetMax());
1057 EXPECT_FALSE(max_increased);
1058
1059 // Average now is 4 runs and (18 * 3 + 5)/ 4 = 14.75 = 14
1060 run3.Save();
1061 AssertStats(path, 4, 14);
1062}
1063
1064// Tests what happens when the persistent settings contains the average duration of 2 runs.
1065// Data on file is 2 runs and 15 average.
1066TEST_F(ProgressTest, ThirdTime) {
1067 std::string path = CopyTextFileFixture("stats-two-runs.txt");
1068 AssertStats(path, 2, 15); // Sanity check
1069
1070 Progress run1 = GetInstance(-42, 1.2, path);
1071 EXPECT_EQ(0, run1.Get());
1072 EXPECT_EQ(15, run1.GetInitialMax());
1073 EXPECT_EQ(15, run1.GetMax());
1074
1075 bool max_increased = run1.Inc(20);
1076 EXPECT_EQ(20, run1.Get());
1077 EXPECT_EQ(24, run1.GetMax());
1078 EXPECT_TRUE(max_increased);
1079
1080 // Average now is 3 runs and (15 * 2 + 20)/ 3 = 16.66 = 16
1081 run1.Save();
1082 AssertStats(path, 3, 16);
1083}
1084
Felipe Leme46b85da2016-11-21 17:40:45 -08001085class DumpstateUtilTest : public DumpstateBaseTest {
1086 public:
1087 void SetUp() {
1088 DumpstateBaseTest::SetUp();
1089 SetDryRun(false);
1090 }
1091
Felipe Leme46b85da2016-11-21 17:40:45 -08001092 void CaptureFdOut() {
Felipe Lemef0292972016-11-22 13:57:05 -08001093 ReadFileToString(path_, &out);
Felipe Leme46b85da2016-11-21 17:40:45 -08001094 }
1095
1096 void CreateFd(const std::string& name) {
1097 path_ = kTestDataPath + name;
1098 MYLOGD("Creating fd for file %s\n", path_.c_str());
1099
1100 fd = TEMP_FAILURE_RETRY(open(path_.c_str(),
1101 O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW,
1102 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH));
1103 ASSERT_GE(fd, 0) << "could not create FD for path " << path_;
1104 }
1105
1106 // Runs a command into the `fd` and capture `stderr`.
Felipe Lemef0292972016-11-22 13:57:05 -08001107 int RunCommand(const std::string& title, const std::vector<std::string>& full_command,
Felipe Leme46b85da2016-11-21 17:40:45 -08001108 const CommandOptions& options = CommandOptions::DEFAULT) {
1109 CaptureStderr();
Felipe Lemef0292972016-11-22 13:57:05 -08001110 int status = RunCommandToFd(fd, title, full_command, options);
Felipe Leme46b85da2016-11-21 17:40:45 -08001111 close(fd);
1112
1113 CaptureFdOut();
1114 err = GetCapturedStderr();
1115 return status;
1116 }
1117
1118 // Dumps a file and into the `fd` and `stderr`.
Felipe Lemef0292972016-11-22 13:57:05 -08001119 int DumpFile(const std::string& title, const std::string& path) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001120 CaptureStderr();
Felipe Lemef0292972016-11-22 13:57:05 -08001121 int status = DumpFileToFd(fd, title, path);
Felipe Leme46b85da2016-11-21 17:40:45 -08001122 close(fd);
1123
1124 CaptureFdOut();
1125 err = GetCapturedStderr();
1126 return status;
1127 }
1128
Ecco Park61ffcf72016-10-27 15:46:26 -07001129 // Find out the pid of the process_name
1130 int FindPidOfProcess(const std::string& process_name) {
1131 CaptureStderr();
1132 int status = GetPidByName(process_name);
1133 err = GetCapturedStderr();
1134 return status;
1135 }
1136
Felipe Leme46b85da2016-11-21 17:40:45 -08001137 int fd;
1138
1139 // 'fd` output and `stderr` from the last command ran.
1140 std::string out, err;
1141
1142 private:
1143 std::string path_;
1144};
1145
1146TEST_F(DumpstateUtilTest, RunCommandNoArgs) {
Felipe Lemef0292972016-11-22 13:57:05 -08001147 CreateFd("RunCommandNoArgs.txt");
1148 EXPECT_EQ(-1, RunCommand("", {}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001149}
1150
Felipe Lemef0292972016-11-22 13:57:05 -08001151TEST_F(DumpstateUtilTest, RunCommandNoTitle) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001152 CreateFd("RunCommandWithNoArgs.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001153 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001154 EXPECT_THAT(out, StrEq("stdout\n"));
1155 EXPECT_THAT(err, StrEq("stderr\n"));
1156}
1157
Felipe Lemef0292972016-11-22 13:57:05 -08001158TEST_F(DumpstateUtilTest, RunCommandWithTitle) {
1159 CreateFd("RunCommandWithNoArgs.txt");
1160 EXPECT_EQ(0, RunCommand("I AM GROOT", {kSimpleCommand}));
1161 EXPECT_THAT(out, StrEq("------ I AM GROOT (" + kSimpleCommand + ") ------\nstdout\n"));
1162 EXPECT_THAT(err, StrEq("stderr\n"));
1163}
1164
Felipe Leme46b85da2016-11-21 17:40:45 -08001165TEST_F(DumpstateUtilTest, RunCommandWithOneArg) {
1166 CreateFd("RunCommandWithOneArg.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001167 EXPECT_EQ(0, RunCommand("", {kEchoCommand, "one"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001168 EXPECT_THAT(err, IsEmpty());
1169 EXPECT_THAT(out, StrEq("one\n"));
1170}
1171
1172TEST_F(DumpstateUtilTest, RunCommandWithMultipleArgs) {
1173 CreateFd("RunCommandWithMultipleArgs.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001174 EXPECT_EQ(0, RunCommand("", {kEchoCommand, "one", "is", "the", "loniest", "number"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001175 EXPECT_THAT(err, IsEmpty());
1176 EXPECT_THAT(out, StrEq("one is the loniest number\n"));
1177}
1178
1179TEST_F(DumpstateUtilTest, RunCommandWithLoggingMessage) {
1180 CreateFd("RunCommandWithLoggingMessage.txt");
1181 EXPECT_EQ(
Felipe Lemef0292972016-11-22 13:57:05 -08001182 0, RunCommand("", {kSimpleCommand},
Felipe Leme46b85da2016-11-21 17:40:45 -08001183 CommandOptions::WithTimeout(10).Log("COMMAND, Y U NO LOG FIRST?").Build()));
1184 EXPECT_THAT(out, StrEq("stdout\n"));
1185 EXPECT_THAT(err, StrEq("COMMAND, Y U NO LOG FIRST?stderr\n"));
1186}
1187
1188TEST_F(DumpstateUtilTest, RunCommandRedirectStderr) {
1189 CreateFd("RunCommandRedirectStderr.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001190 EXPECT_EQ(0, RunCommand("", {kSimpleCommand},
1191 CommandOptions::WithTimeout(10).RedirectStderr().Build()));
Felipe Leme46b85da2016-11-21 17:40:45 -08001192 EXPECT_THAT(out, IsEmpty());
1193 EXPECT_THAT(err, StrEq("stdout\nstderr\n"));
1194}
1195
1196TEST_F(DumpstateUtilTest, RunCommandDryRun) {
1197 CreateFd("RunCommandDryRun.txt");
1198 SetDryRun(true);
Felipe Lemef0292972016-11-22 13:57:05 -08001199 EXPECT_EQ(0, RunCommand("I AM GROOT", {kSimpleCommand}));
1200 EXPECT_THAT(out, StrEq(android::base::StringPrintf(
1201 "------ I AM GROOT (%s) ------\n\t(skipped on dry run)\n",
1202 kSimpleCommand.c_str())));
1203 EXPECT_THAT(err, IsEmpty());
1204}
1205
1206TEST_F(DumpstateUtilTest, RunCommandDryRunNoTitle) {
1207 CreateFd("RunCommandDryRun.txt");
1208 SetDryRun(true);
1209 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001210 EXPECT_THAT(
1211 out, StrEq(android::base::StringPrintf("%s: skipped on dry run\n", kSimpleCommand.c_str())));
1212 EXPECT_THAT(err, IsEmpty());
1213}
1214
1215TEST_F(DumpstateUtilTest, RunCommandDryRunAlways) {
1216 CreateFd("RunCommandDryRunAlways.txt");
1217 SetDryRun(true);
Felipe Lemef0292972016-11-22 13:57:05 -08001218 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(10).Always().Build()));
Felipe Leme46b85da2016-11-21 17:40:45 -08001219 EXPECT_THAT(out, StrEq("stdout\n"));
1220 EXPECT_THAT(err, StrEq("stderr\n"));
1221}
1222
1223TEST_F(DumpstateUtilTest, RunCommandNotFound) {
1224 CreateFd("RunCommandNotFound.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001225 EXPECT_NE(0, RunCommand("", {"/there/cannot/be/such/command"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001226 EXPECT_THAT(out, StartsWith("*** command '/there/cannot/be/such/command' failed: exit code"));
1227 EXPECT_THAT(err, StartsWith("execvp on command '/there/cannot/be/such/command' failed"));
1228}
1229
1230TEST_F(DumpstateUtilTest, RunCommandFails) {
1231 CreateFd("RunCommandFails.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001232 EXPECT_EQ(42, RunCommand("", {kSimpleCommand, "--exit", "42"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001233 EXPECT_THAT(out, StrEq("stdout\n*** command '" + kSimpleCommand +
1234 " --exit 42' failed: exit code 42\n"));
1235 EXPECT_THAT(err, StrEq("stderr\n*** command '" + kSimpleCommand +
1236 " --exit 42' failed: exit code 42\n"));
1237}
1238
1239TEST_F(DumpstateUtilTest, RunCommandCrashes) {
1240 CreateFd("RunCommandCrashes.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001241 EXPECT_NE(0, RunCommand("", {kSimpleCommand, "--crash"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001242 // We don't know the exit code, so check just the prefix.
1243 EXPECT_THAT(
1244 out, StartsWith("stdout\n*** command '" + kSimpleCommand + " --crash' failed: exit code"));
1245 EXPECT_THAT(
1246 err, StartsWith("stderr\n*** command '" + kSimpleCommand + " --crash' failed: exit code"));
1247}
1248
Vishnu Nair6921f802017-11-22 09:17:23 -08001249TEST_F(DumpstateUtilTest, RunCommandTimesoutWithSec) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001250 CreateFd("RunCommandTimesout.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001251 EXPECT_EQ(-1, RunCommand("", {kSimpleCommand, "--sleep", "2"},
1252 CommandOptions::WithTimeout(1).Build()));
Felipe Leme46b85da2016-11-21 17:40:45 -08001253 EXPECT_THAT(out, StartsWith("stdout line1\n*** command '" + kSimpleCommand +
1254 " --sleep 2' timed out after 1"));
1255 EXPECT_THAT(err, StartsWith("sleeping for 2s\n*** command '" + kSimpleCommand +
1256 " --sleep 2' timed out after 1"));
1257}
1258
Vishnu Nair6921f802017-11-22 09:17:23 -08001259TEST_F(DumpstateUtilTest, RunCommandTimesoutWithMsec) {
1260 CreateFd("RunCommandTimesout.txt");
1261 EXPECT_EQ(-1, RunCommand("", {kSimpleCommand, "--sleep", "2"},
1262 CommandOptions::WithTimeoutInMs(1000).Build()));
1263 EXPECT_THAT(out, StartsWith("stdout line1\n*** command '" + kSimpleCommand +
1264 " --sleep 2' timed out after 1"));
1265 EXPECT_THAT(err, StartsWith("sleeping for 2s\n*** command '" + kSimpleCommand +
1266 " --sleep 2' timed out after 1"));
1267}
1268
1269
Felipe Leme46b85da2016-11-21 17:40:45 -08001270TEST_F(DumpstateUtilTest, RunCommandIsKilled) {
1271 CreateFd("RunCommandIsKilled.txt");
1272 CaptureStderr();
1273
1274 std::thread t([=]() {
Felipe Lemef0292972016-11-22 13:57:05 -08001275 EXPECT_EQ(SIGTERM, RunCommandToFd(fd, "", {kSimpleCommand, "--pid", "--sleep", "20"},
Felipe Leme46b85da2016-11-21 17:40:45 -08001276 CommandOptions::WithTimeout(100).Always().Build()));
1277 });
1278
1279 // Capture pid and pre-sleep output.
1280 sleep(1); // Wait a little bit to make sure pid and 1st line were printed.
1281 std::string err = GetCapturedStderr();
1282 EXPECT_THAT(err, StrEq("sleeping for 20s\n"));
1283
1284 CaptureFdOut();
1285 std::vector<std::string> lines = android::base::Split(out, "\n");
1286 ASSERT_EQ(3, (int)lines.size()) << "Invalid lines before sleep: " << out;
1287
1288 int pid = atoi(lines[0].c_str());
1289 EXPECT_THAT(lines[1], StrEq("stdout line1"));
1290 EXPECT_THAT(lines[2], IsEmpty()); // \n
1291
1292 // Then kill the process.
1293 CaptureFdOut();
1294 CaptureStderr();
1295 ASSERT_EQ(0, kill(pid, SIGTERM)) << "failed to kill pid " << pid;
1296 t.join();
1297
1298 // Finally, check output after murder.
1299 CaptureFdOut();
1300 err = GetCapturedStderr();
1301
1302 // out starts with the pid, which is an unknown
1303 EXPECT_THAT(out, EndsWith("stdout line1\n*** command '" + kSimpleCommand +
1304 " --pid --sleep 20' failed: killed by signal 15\n"));
1305 EXPECT_THAT(err, StrEq("*** command '" + kSimpleCommand +
1306 " --pid --sleep 20' failed: killed by signal 15\n"));
1307}
1308
1309TEST_F(DumpstateUtilTest, RunCommandAsRootUserBuild) {
1310 if (!IsStandalone()) {
1311 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1312 // to Shell - need to refactor tests to avoid this problem)
1313 MYLOGE("Skipping DumpstateUtilTest.RunCommandAsRootUserBuild() on test suite\n")
1314 return;
1315 }
1316 CreateFd("RunCommandAsRootUserBuild.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001317 if (!PropertiesHelper::IsUserBuild()) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001318 // Emulates user build if necessarily.
1319 SetBuildType("user");
1320 }
1321
1322 DropRoot();
1323
Felipe Lemef0292972016-11-22 13:57:05 -08001324 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).AsRoot().Build()));
Felipe Leme46b85da2016-11-21 17:40:45 -08001325
1326 // We don't know the exact path of su, so we just check for the 'root ...' commands
1327 EXPECT_THAT(out, StartsWith("Skipping"));
1328 EXPECT_THAT(out, EndsWith("root " + kSimpleCommand + "' on user build.\n"));
1329 EXPECT_THAT(err, IsEmpty());
1330}
1331
1332TEST_F(DumpstateUtilTest, RunCommandAsRootNonUserBuild) {
1333 if (!IsStandalone()) {
1334 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1335 // to Shell - need to refactor tests to avoid this problem)
1336 MYLOGE("Skipping DumpstateUtilTest.RunCommandAsRootNonUserBuild() on test suite\n")
1337 return;
1338 }
1339 CreateFd("RunCommandAsRootNonUserBuild.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001340 if (PropertiesHelper::IsUserBuild()) {
Felipe Leme7447d7c2016-11-03 18:12:22 -07001341 ALOGI("Skipping RunCommandAsRootNonUserBuild on user builds\n");
1342 return;
1343 }
1344
1345 DropRoot();
1346
Felipe Lemef0292972016-11-22 13:57:05 -08001347 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
1348 CommandOptions::WithTimeout(1).AsRoot().Build()));
Felipe Leme7447d7c2016-11-03 18:12:22 -07001349
1350 EXPECT_THAT(out, StrEq("0\nstdout\n"));
1351 EXPECT_THAT(err, StrEq("stderr\n"));
1352}
Felipe Leme46b85da2016-11-21 17:40:45 -08001353
Yifan Hong48e83a12017-10-03 14:10:07 -07001354
1355TEST_F(DumpstateUtilTest, RunCommandAsRootIfAvailableOnUserBuild) {
1356 if (!IsStandalone()) {
1357 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1358 // to Shell - need to refactor tests to avoid this problem)
1359 MYLOGE("Skipping DumpstateUtilTest.RunCommandAsRootIfAvailableOnUserBuild() on test suite\n")
1360 return;
1361 }
1362 CreateFd("RunCommandAsRootIfAvailableOnUserBuild.txt");
1363 if (!PropertiesHelper::IsUserBuild()) {
1364 // Emulates user build if necessarily.
1365 SetBuildType("user");
1366 }
1367
1368 DropRoot();
1369
1370 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
1371 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
1372
1373 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
1374 EXPECT_THAT(err, StrEq("stderr\n"));
1375}
1376
1377TEST_F(DumpstateUtilTest, RunCommandAsRootIfAvailableOnDebugBuild) {
1378 if (!IsStandalone()) {
1379 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1380 // to Shell - need to refactor tests to avoid this problem)
1381 MYLOGE("Skipping DumpstateUtilTest.RunCommandAsRootIfAvailableOnDebugBuild() on test suite\n")
1382 return;
1383 }
1384 CreateFd("RunCommandAsRootIfAvailableOnDebugBuild.txt");
1385 if (PropertiesHelper::IsUserBuild()) {
1386 ALOGI("Skipping RunCommandAsRootNonUserBuild on user builds\n");
1387 return;
1388 }
1389
1390 DropRoot();
1391
1392 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
1393 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
1394
1395 EXPECT_THAT(out, StrEq("0\nstdout\n"));
1396 EXPECT_THAT(err, StrEq("stderr\n"));
1397}
1398
Felipe Leme46b85da2016-11-21 17:40:45 -08001399TEST_F(DumpstateUtilTest, RunCommandDropRoot) {
1400 if (!IsStandalone()) {
1401 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1402 // to Shell - need to refactor tests to avoid this problem)
1403 MYLOGE("Skipping DumpstateUtilTest.RunCommandDropRoot() on test suite\n")
1404 return;
1405 }
1406 CreateFd("RunCommandDropRoot.txt");
1407 // First check root case - only available when running with 'adb root'.
1408 uid_t uid = getuid();
1409 if (uid == 0) {
Felipe Lemef0292972016-11-22 13:57:05 -08001410 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001411 EXPECT_THAT(out, StrEq("0\nstdout\n"));
1412 EXPECT_THAT(err, StrEq("stderr\n"));
1413 return;
1414 }
1415 // Then run dropping root.
Felipe Lemef0292972016-11-22 13:57:05 -08001416 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
Felipe Leme46b85da2016-11-21 17:40:45 -08001417 CommandOptions::WithTimeout(1).DropRoot().Build()));
1418 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
1419 EXPECT_THAT(err, StrEq("drop_root_user(): already running as Shell\nstderr\n"));
1420}
1421
Felipe Lemef0292972016-11-22 13:57:05 -08001422TEST_F(DumpstateUtilTest, DumpFileNotFoundNoTitle) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001423 CreateFd("DumpFileNotFound.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001424 EXPECT_EQ(-1, DumpFile("", "/I/cant/believe/I/exist"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001425 EXPECT_THAT(out,
1426 StrEq("*** Error dumping /I/cant/believe/I/exist: No such file or directory\n"));
1427 EXPECT_THAT(err, IsEmpty());
1428}
1429
Felipe Lemef0292972016-11-22 13:57:05 -08001430TEST_F(DumpstateUtilTest, DumpFileNotFoundWithTitle) {
1431 CreateFd("DumpFileNotFound.txt");
1432 EXPECT_EQ(-1, DumpFile("Y U NO EXIST?", "/I/cant/believe/I/exist"));
1433 EXPECT_THAT(out, StrEq("*** Error dumping /I/cant/believe/I/exist (Y U NO EXIST?): No such "
1434 "file or directory\n"));
1435 EXPECT_THAT(err, IsEmpty());
1436}
1437
Felipe Leme46b85da2016-11-21 17:40:45 -08001438TEST_F(DumpstateUtilTest, DumpFileSingleLine) {
1439 CreateFd("DumpFileSingleLine.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001440 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001441 EXPECT_THAT(err, IsEmpty());
1442 EXPECT_THAT(out, StrEq("I AM LINE1\n")); // dumpstate adds missing newline
1443}
1444
1445TEST_F(DumpstateUtilTest, DumpFileSingleLineWithNewLine) {
1446 CreateFd("DumpFileSingleLineWithNewLine.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001447 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line-with-newline.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001448 EXPECT_THAT(err, IsEmpty());
1449 EXPECT_THAT(out, StrEq("I AM LINE1\n"));
1450}
1451
1452TEST_F(DumpstateUtilTest, DumpFileMultipleLines) {
1453 CreateFd("DumpFileMultipleLines.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001454 EXPECT_EQ(0, DumpFile("", kTestDataPath + "multiple-lines.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001455 EXPECT_THAT(err, IsEmpty());
1456 EXPECT_THAT(out, StrEq("I AM LINE1\nI AM LINE2\nI AM LINE3\n"));
1457}
1458
1459TEST_F(DumpstateUtilTest, DumpFileMultipleLinesWithNewLine) {
1460 CreateFd("DumpFileMultipleLinesWithNewLine.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001461 EXPECT_EQ(0, DumpFile("", kTestDataPath + "multiple-lines-with-newline.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001462 EXPECT_THAT(err, IsEmpty());
1463 EXPECT_THAT(out, StrEq("I AM LINE1\nI AM LINE2\nI AM LINE3\n"));
1464}
1465
Felipe Lemef0292972016-11-22 13:57:05 -08001466TEST_F(DumpstateUtilTest, DumpFileOnDryRunNoTitle) {
1467 CreateFd("DumpFileOnDryRun.txt");
1468 SetDryRun(true);
1469 std::string path = kTestDataPath + "single-line.txt";
1470 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
1471 EXPECT_THAT(err, IsEmpty());
1472 EXPECT_THAT(out, StrEq(path + ": skipped on dry run\n"));
1473}
1474
Felipe Leme46b85da2016-11-21 17:40:45 -08001475TEST_F(DumpstateUtilTest, DumpFileOnDryRun) {
1476 CreateFd("DumpFileOnDryRun.txt");
1477 SetDryRun(true);
1478 std::string path = kTestDataPath + "single-line.txt";
Felipe Lemef0292972016-11-22 13:57:05 -08001479 EXPECT_EQ(0, DumpFile("Might as well dump. Dump!", kTestDataPath + "single-line.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001480 EXPECT_THAT(err, IsEmpty());
Felipe Lemef0292972016-11-22 13:57:05 -08001481 EXPECT_THAT(
1482 out, StartsWith("------ Might as well dump. Dump! (" + kTestDataPath + "single-line.txt:"));
1483 EXPECT_THAT(out, EndsWith("skipped on dry run\n"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001484}
Ecco Park61ffcf72016-10-27 15:46:26 -07001485
1486TEST_F(DumpstateUtilTest, FindingPidWithExistingProcess) {
1487 // init process always has pid 1.
1488 EXPECT_EQ(1, FindPidOfProcess("init"));
1489 EXPECT_THAT(err, IsEmpty());
1490}
1491
1492TEST_F(DumpstateUtilTest, FindingPidWithNotExistingProcess) {
1493 // find the process with abnormal name.
1494 EXPECT_EQ(-1, FindPidOfProcess("abcdef12345-543"));
1495 EXPECT_THAT(err, StrEq("can't find the pid\n"));
1496}
Felipe Leme47e9be22016-12-21 15:37:07 -08001497
1498} // namespace dumpstate
1499} // namespace os
1500} // namespace android