blob: 27b3130123f631c8f84204d5c104c6b1fc8f9348 [file] [log] [blame]
Felipe Leme4c2d6632016-09-28 14:32:00 -07001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Felipe Leme75876a22016-10-27 16:31:27 -070017#define LOG_TAG "dumpstate"
18#include <cutils/log.h>
19
Felipe Lemef0292972016-11-22 13:57:05 -080020#include "DumpstateInternal.h"
Felipe Leme75876a22016-10-27 16:31:27 -070021#include "DumpstateService.h"
22#include "android/os/BnDumpstate.h"
Felipe Leme4c2d6632016-09-28 14:32:00 -070023#include "dumpstate.h"
24
25#include <gmock/gmock.h>
26#include <gtest/gtest.h>
27
Felipe Leme46b85da2016-11-21 17:40:45 -080028#include <fcntl.h>
Felipe Leme4c2d6632016-09-28 14:32:00 -070029#include <libgen.h>
Felipe Lemefd8affa2016-09-30 17:38:57 -070030#include <signal.h>
31#include <sys/types.h>
Felipe Leme4c2d6632016-09-28 14:32:00 -070032#include <unistd.h>
Felipe Lemefd8affa2016-09-30 17:38:57 -070033#include <thread>
Felipe Leme4c2d6632016-09-28 14:32:00 -070034
35#include <android-base/file.h>
Felipe Lemed80e6b62016-10-03 13:08:14 -070036#include <android-base/properties.h>
37#include <android-base/stringprintf.h>
Felipe Lemefd8affa2016-09-30 17:38:57 -070038#include <android-base/strings.h>
Abhijeet Kaur904e0e02018-12-05 14:03:01 +000039#include <cutils/properties.h>
Felipe Leme4c2d6632016-09-28 14:32:00 -070040
Felipe Leme47e9be22016-12-21 15:37:07 -080041namespace android {
42namespace os {
43namespace dumpstate {
Felipe Lemed80e6b62016-10-03 13:08:14 -070044
Felipe Leme4c2d6632016-09-28 14:32:00 -070045using ::testing::EndsWith;
Felipe Leme46b85da2016-11-21 17:40:45 -080046using ::testing::HasSubstr;
Felipe Leme009ecbb2016-11-07 10:18:44 -080047using ::testing::IsNull;
Felipe Leme4c2d6632016-09-28 14:32:00 -070048using ::testing::IsEmpty;
Felipe Leme009ecbb2016-11-07 10:18:44 -080049using ::testing::NotNull;
Felipe Leme4c2d6632016-09-28 14:32:00 -070050using ::testing::StrEq;
51using ::testing::StartsWith;
52using ::testing::Test;
53using ::testing::internal::CaptureStderr;
54using ::testing::internal::CaptureStdout;
55using ::testing::internal::GetCapturedStderr;
56using ::testing::internal::GetCapturedStdout;
57
Nandana Dutt3f8c7172018-09-25 12:01:54 +010058#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
59
Felipe Leme75876a22016-10-27 16:31:27 -070060class DumpstateListenerMock : public IDumpstateListener {
61 public:
Nandana Dutta6a28bd2019-01-14 16:54:38 +000062 MOCK_METHOD1(onProgress, binder::Status(int32_t progress));
63 MOCK_METHOD1(onError, binder::Status(int32_t error_code));
Nandana Duttcc4ead82019-01-23 08:29:23 +000064 MOCK_METHOD0(onFinished, binder::Status());
Felipe Leme75876a22016-10-27 16:31:27 -070065 MOCK_METHOD1(onProgressUpdated, binder::Status(int32_t progress));
66 MOCK_METHOD1(onMaxProgressUpdated, binder::Status(int32_t max_progress));
Vishnu Nair20cf5032018-01-05 13:15:49 -080067 MOCK_METHOD4(onSectionComplete, binder::Status(const ::std::string& name, int32_t status,
68 int32_t size, int32_t durationMs));
Felipe Leme75876a22016-10-27 16:31:27 -070069
70 protected:
71 MOCK_METHOD0(onAsBinder, IBinder*());
72};
73
Felipe Leme46b85da2016-11-21 17:40:45 -080074static int calls_;
75
Felipe Leme7447d7c2016-11-03 18:12:22 -070076// Base class for all tests in this file
77class DumpstateBaseTest : public Test {
Felipe Leme46b85da2016-11-21 17:40:45 -080078 public:
79 virtual void SetUp() override {
80 calls_++;
Felipe Lemef0292972016-11-22 13:57:05 -080081 SetDryRun(false);
Felipe Leme46b85da2016-11-21 17:40:45 -080082 }
83
Felipe Lemef0292972016-11-22 13:57:05 -080084 void SetDryRun(bool dry_run) const {
85 PropertiesHelper::dry_run_ = dry_run;
86 }
87
88 void SetBuildType(const std::string& build_type) const {
89 PropertiesHelper::build_type_ = build_type;
90 }
91
Nandana Dutt4b392be2018-11-02 16:17:05 +000092 void SetUnroot(bool unroot) const {
93 PropertiesHelper::unroot_ = unroot;
94 }
95
Felipe Lemef0292972016-11-22 13:57:05 -080096 bool IsStandalone() const {
Felipe Leme46b85da2016-11-21 17:40:45 -080097 return calls_ == 1;
98 }
99
Felipe Lemef0292972016-11-22 13:57:05 -0800100 void DropRoot() const {
101 DropRootUser();
Felipe Leme46b85da2016-11-21 17:40:45 -0800102 uid_t uid = getuid();
103 ASSERT_EQ(2000, (int)uid);
104 }
105
Felipe Leme7447d7c2016-11-03 18:12:22 -0700106 protected:
107 const std::string kTestPath = dirname(android::base::GetExecutablePath().c_str());
108 const std::string kFixturesPath = kTestPath + "/../dumpstate_test_fixture/";
Felipe Leme7fb8dee2017-08-25 10:15:01 -0700109 const std::string kTestDataPath = kFixturesPath + "tests/testdata/";
Felipe Leme7447d7c2016-11-03 18:12:22 -0700110 const std::string kSimpleCommand = kFixturesPath + "dumpstate_test_fixture";
111 const std::string kEchoCommand = "/system/bin/echo";
112
113 /*
114 * Copies a text file fixture to a temporary file, returning it's path.
115 *
116 * Useful in cases where the test case changes the content of the tile.
117 */
118 std::string CopyTextFileFixture(const std::string& relative_name) {
119 std::string from = kTestDataPath + relative_name;
120 // Not using TemporaryFile because it's deleted at the end, and it's useful to keep it
121 // around for poking when the test fails.
122 std::string to = kTestDataPath + relative_name + ".tmp";
123 ALOGD("CopyTextFileFixture: from %s to %s\n", from.c_str(), to.c_str());
124 android::base::RemoveFileIfExists(to);
125 CopyTextFile(from, to);
126 return to.c_str();
127 }
128
Felipe Leme46b85da2016-11-21 17:40:45 -0800129 // Need functions that returns void to use assertions -
Felipe Leme7447d7c2016-11-03 18:12:22 -0700130 // https://github.com/google/googletest/blob/master/googletest/docs/AdvancedGuide.md#assertion-placement
Felipe Leme46b85da2016-11-21 17:40:45 -0800131 void ReadFileToString(const std::string& path, std::string* content) {
132 ASSERT_TRUE(android::base::ReadFileToString(path, content))
133 << "could not read contents from " << path;
134 }
135 void WriteStringToFile(const std::string& content, const std::string& path) {
136 ASSERT_TRUE(android::base::WriteStringToFile(content, path))
137 << "could not write contents to " << path;
138 }
139
140 private:
Felipe Leme7447d7c2016-11-03 18:12:22 -0700141 void CopyTextFile(const std::string& from, const std::string& to) {
142 std::string content;
Felipe Leme46b85da2016-11-21 17:40:45 -0800143 ReadFileToString(from, &content);
144 WriteStringToFile(content, to);
Felipe Leme7447d7c2016-11-03 18:12:22 -0700145 }
146};
147
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100148class DumpOptionsTest : public Test {
149 public:
150 virtual ~DumpOptionsTest() {
151 }
152 virtual void SetUp() {
153 options_ = Dumpstate::DumpOptions();
154 }
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000155 void TearDown() {
156 // Reset the property
157 property_set("dumpstate.options", "");
158 }
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100159 Dumpstate::DumpOptions options_;
160};
161
162TEST_F(DumpOptionsTest, InitializeNone) {
163 // clang-format off
164 char* argv[] = {
165 const_cast<char*>("dumpstate")
166 };
167 // clang-format on
168
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100169 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
170
171 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
Nandana Dutt58d72e22018-11-16 10:30:48 +0000172
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100173 EXPECT_FALSE(options_.do_add_date);
174 EXPECT_FALSE(options_.do_zip_file);
175 EXPECT_EQ("", options_.use_outfile);
176 EXPECT_FALSE(options_.use_socket);
177 EXPECT_FALSE(options_.use_control_socket);
178 EXPECT_FALSE(options_.show_header_only);
179 EXPECT_TRUE(options_.do_vibrate);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000180 EXPECT_FALSE(options_.do_fb);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100181 EXPECT_FALSE(options_.do_progress_updates);
182 EXPECT_FALSE(options_.is_remote_mode);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000183 EXPECT_FALSE(options_.do_broadcast);
184}
185
186TEST_F(DumpOptionsTest, InitializeAdbBugreport) {
187 // clang-format off
188 char* argv[] = {
189 const_cast<char*>("dumpstatez"),
190 const_cast<char*>("-S"),
191 const_cast<char*>("-d"),
192 const_cast<char*>("-z"),
193 const_cast<char*>("-o abc"),
194 };
195 // clang-format on
196
197 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
198
199 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
200 EXPECT_TRUE(options_.do_add_date);
201 EXPECT_TRUE(options_.do_zip_file);
202 EXPECT_TRUE(options_.use_control_socket);
203 EXPECT_EQ(" abc", std::string(options_.use_outfile));
204
205 // Other options retain default values
206 EXPECT_TRUE(options_.do_vibrate);
207 EXPECT_FALSE(options_.show_header_only);
208 EXPECT_FALSE(options_.do_fb);
209 EXPECT_FALSE(options_.do_progress_updates);
210 EXPECT_FALSE(options_.is_remote_mode);
211 EXPECT_FALSE(options_.do_broadcast);
212 EXPECT_FALSE(options_.use_socket);
213}
214
215TEST_F(DumpOptionsTest, InitializeAdbShellBugreport) {
216 // clang-format off
217 char* argv[] = {
218 const_cast<char*>("dumpstate"),
219 const_cast<char*>("-s"),
220 };
221 // clang-format on
222
223 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
224
225 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
226 EXPECT_TRUE(options_.use_socket);
227
228 // Other options retain default values
229 EXPECT_TRUE(options_.do_vibrate);
230 EXPECT_EQ("", options_.use_outfile);
231 EXPECT_FALSE(options_.do_add_date);
232 EXPECT_FALSE(options_.do_zip_file);
233 EXPECT_FALSE(options_.use_control_socket);
234 EXPECT_FALSE(options_.show_header_only);
235 EXPECT_FALSE(options_.do_fb);
236 EXPECT_FALSE(options_.do_progress_updates);
237 EXPECT_FALSE(options_.is_remote_mode);
238 EXPECT_FALSE(options_.do_broadcast);
239}
240
241TEST_F(DumpOptionsTest, InitializeFullBugReport) {
242 // clang-format off
243 char* argv[] = {
244 const_cast<char*>("bugreport"),
245 const_cast<char*>("-d"),
246 const_cast<char*>("-p"),
247 const_cast<char*>("-B"),
248 const_cast<char*>("-z"),
249 const_cast<char*>("-o abc"),
250 };
251 // clang-format on
252 property_set("dumpstate.options", "bugreportfull");
253
254 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
255
256 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
257 EXPECT_TRUE(options_.do_add_date);
258 EXPECT_TRUE(options_.do_fb);
259 EXPECT_TRUE(options_.do_zip_file);
Nandana Dutt58d72e22018-11-16 10:30:48 +0000260 EXPECT_TRUE(options_.do_broadcast);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000261 EXPECT_EQ(" abc", std::string(options_.use_outfile));
262
263 // Other options retain default values
264 EXPECT_TRUE(options_.do_vibrate);
265 EXPECT_FALSE(options_.use_control_socket);
266 EXPECT_FALSE(options_.show_header_only);
267 EXPECT_FALSE(options_.do_progress_updates);
268 EXPECT_FALSE(options_.is_remote_mode);
269 EXPECT_FALSE(options_.use_socket);
270 EXPECT_FALSE(options_.do_start_service);
271}
272
273TEST_F(DumpOptionsTest, InitializeInteractiveBugReport) {
274 // clang-format off
275 char* argv[] = {
276 const_cast<char*>("bugreport"),
277 const_cast<char*>("-d"),
278 const_cast<char*>("-p"),
279 const_cast<char*>("-B"),
280 const_cast<char*>("-z"),
281 const_cast<char*>("-o abc"),
282 };
283 // clang-format on
284
285 property_set("dumpstate.options", "bugreportplus");
286
287 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
288
289 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
290 EXPECT_TRUE(options_.do_add_date);
291 EXPECT_TRUE(options_.do_broadcast);
292 EXPECT_TRUE(options_.do_zip_file);
293 EXPECT_TRUE(options_.do_progress_updates);
294 EXPECT_TRUE(options_.do_start_service);
295 EXPECT_FALSE(options_.do_fb);
296 EXPECT_EQ(" abc", std::string(options_.use_outfile));
297
298 // Other options retain default values
299 EXPECT_TRUE(options_.do_vibrate);
300 EXPECT_FALSE(options_.use_control_socket);
301 EXPECT_FALSE(options_.show_header_only);
302 EXPECT_FALSE(options_.is_remote_mode);
303 EXPECT_FALSE(options_.use_socket);
304}
305
306TEST_F(DumpOptionsTest, InitializeRemoteBugReport) {
307 // clang-format off
308 char* argv[] = {
309 const_cast<char*>("bugreport"),
310 const_cast<char*>("-d"),
311 const_cast<char*>("-p"),
312 const_cast<char*>("-B"),
313 const_cast<char*>("-z"),
314 const_cast<char*>("-o abc"),
315 };
316 // clang-format on
317
318 property_set("dumpstate.options", "bugreportremote");
319
320 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
321
322 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
323 EXPECT_TRUE(options_.do_add_date);
324 EXPECT_TRUE(options_.do_broadcast);
325 EXPECT_TRUE(options_.do_zip_file);
326 EXPECT_TRUE(options_.is_remote_mode);
327 EXPECT_FALSE(options_.do_vibrate);
328 EXPECT_FALSE(options_.do_fb);
329 EXPECT_EQ(" abc", std::string(options_.use_outfile));
330
331 // Other options retain default values
332 EXPECT_FALSE(options_.use_control_socket);
333 EXPECT_FALSE(options_.show_header_only);
334 EXPECT_FALSE(options_.do_progress_updates);
335 EXPECT_FALSE(options_.use_socket);
336}
337
338TEST_F(DumpOptionsTest, InitializeWearBugReport) {
339 // clang-format off
340 char* argv[] = {
341 const_cast<char*>("bugreport"),
342 const_cast<char*>("-d"),
343 const_cast<char*>("-p"),
344 const_cast<char*>("-B"),
345 const_cast<char*>("-z"),
346 const_cast<char*>("-o abc"),
347 };
348 // clang-format on
349
350 property_set("dumpstate.options", "bugreportwear");
351
352 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
353
354 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
355 EXPECT_TRUE(options_.do_add_date);
356 EXPECT_TRUE(options_.do_fb);
357 EXPECT_TRUE(options_.do_broadcast);
358 EXPECT_TRUE(options_.do_zip_file);
359 EXPECT_TRUE(options_.do_progress_updates);
360 EXPECT_TRUE(options_.do_start_service);
361 EXPECT_EQ(" abc", std::string(options_.use_outfile));
362
363 // Other options retain default values
364 EXPECT_TRUE(options_.do_vibrate);
365 EXPECT_FALSE(options_.use_control_socket);
366 EXPECT_FALSE(options_.show_header_only);
367 EXPECT_FALSE(options_.is_remote_mode);
368 EXPECT_FALSE(options_.use_socket);
369}
370
371TEST_F(DumpOptionsTest, InitializeTelephonyBugReport) {
372 // clang-format off
373 char* argv[] = {
374 const_cast<char*>("bugreport"),
375 const_cast<char*>("-d"),
376 const_cast<char*>("-p"),
377 const_cast<char*>("-B"),
378 const_cast<char*>("-z"),
379 const_cast<char*>("-o abc"),
380 };
381 // clang-format on
382
383 property_set("dumpstate.options", "bugreporttelephony");
384
385 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
386
387 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
388 EXPECT_TRUE(options_.do_add_date);
389 EXPECT_TRUE(options_.do_fb);
390 EXPECT_TRUE(options_.do_broadcast);
391 EXPECT_TRUE(options_.do_zip_file);
392 EXPECT_TRUE(options_.telephony_only);
393 EXPECT_EQ(" abc", std::string(options_.use_outfile));
394
395 // Other options retain default values
396 EXPECT_TRUE(options_.do_vibrate);
397 EXPECT_FALSE(options_.use_control_socket);
398 EXPECT_FALSE(options_.show_header_only);
399 EXPECT_FALSE(options_.do_progress_updates);
400 EXPECT_FALSE(options_.is_remote_mode);
401 EXPECT_FALSE(options_.use_socket);
402}
403
404TEST_F(DumpOptionsTest, InitializeWifiBugReport) {
405 // clang-format off
406 char* argv[] = {
407 const_cast<char*>("bugreport"),
408 const_cast<char*>("-d"),
409 const_cast<char*>("-p"),
410 const_cast<char*>("-B"),
411 const_cast<char*>("-z"),
412 const_cast<char*>("-o abc"),
413 };
414 // clang-format on
415
416 property_set("dumpstate.options", "bugreportwifi");
417
418 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
419
420 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
421 EXPECT_TRUE(options_.do_add_date);
422 EXPECT_TRUE(options_.do_fb);
423 EXPECT_TRUE(options_.do_broadcast);
424 EXPECT_TRUE(options_.do_zip_file);
425 EXPECT_TRUE(options_.wifi_only);
426 EXPECT_EQ(" abc", std::string(options_.use_outfile));
427
428 // Other options retain default values
429 EXPECT_TRUE(options_.do_vibrate);
430 EXPECT_FALSE(options_.use_control_socket);
431 EXPECT_FALSE(options_.show_header_only);
432 EXPECT_FALSE(options_.do_progress_updates);
433 EXPECT_FALSE(options_.is_remote_mode);
434 EXPECT_FALSE(options_.use_socket);
435}
436
437TEST_F(DumpOptionsTest, InitializeDefaultBugReport) {
438 // default: commandline options are not overridden
439 // clang-format off
440 char* argv[] = {
441 const_cast<char*>("bugreport"),
442 const_cast<char*>("-d"),
443 const_cast<char*>("-p"),
444 const_cast<char*>("-B"),
445 const_cast<char*>("-z"),
446 const_cast<char*>("-o abc"),
447 };
448 // clang-format on
449
450 property_set("dumpstate.options", "");
451
452 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
453
454 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
455 EXPECT_TRUE(options_.do_add_date);
456 EXPECT_TRUE(options_.do_fb);
457 EXPECT_TRUE(options_.do_zip_file);
458 EXPECT_TRUE(options_.do_broadcast);
459 EXPECT_EQ(" abc", std::string(options_.use_outfile));
460
461 // Other options retain default values
462 EXPECT_TRUE(options_.do_vibrate);
463 EXPECT_FALSE(options_.use_control_socket);
464 EXPECT_FALSE(options_.show_header_only);
465 EXPECT_FALSE(options_.do_progress_updates);
466 EXPECT_FALSE(options_.is_remote_mode);
467 EXPECT_FALSE(options_.use_socket);
468 EXPECT_FALSE(options_.wifi_only);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100469}
470
471TEST_F(DumpOptionsTest, InitializePartial1) {
472 // clang-format off
473 char* argv[] = {
474 const_cast<char*>("dumpstate"),
475 const_cast<char*>("-d"),
476 const_cast<char*>("-z"),
477 const_cast<char*>("-o abc"),
478 const_cast<char*>("-s"),
479 const_cast<char*>("-S"),
480
481 };
482 // clang-format on
483
484 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
485
486 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
487 EXPECT_TRUE(options_.do_add_date);
488 EXPECT_TRUE(options_.do_zip_file);
489 // TODO: Maybe we should trim the filename
490 EXPECT_EQ(" abc", std::string(options_.use_outfile));
491 EXPECT_TRUE(options_.use_socket);
492 EXPECT_TRUE(options_.use_control_socket);
493
494 // Other options retain default values
495 EXPECT_FALSE(options_.show_header_only);
496 EXPECT_TRUE(options_.do_vibrate);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000497 EXPECT_FALSE(options_.do_fb);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100498 EXPECT_FALSE(options_.do_progress_updates);
499 EXPECT_FALSE(options_.is_remote_mode);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000500 EXPECT_FALSE(options_.do_broadcast);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100501}
502
503TEST_F(DumpOptionsTest, InitializePartial2) {
504 // clang-format off
505 char* argv[] = {
506 const_cast<char*>("dumpstate"),
507 const_cast<char*>("-v"),
508 const_cast<char*>("-q"),
509 const_cast<char*>("-p"),
510 const_cast<char*>("-P"),
511 const_cast<char*>("-R"),
512 const_cast<char*>("-B"),
513 };
514 // clang-format on
515
516 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
517
518 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
519 EXPECT_TRUE(options_.show_header_only);
520 EXPECT_FALSE(options_.do_vibrate);
521 EXPECT_TRUE(options_.do_fb);
522 EXPECT_TRUE(options_.do_progress_updates);
523 EXPECT_TRUE(options_.is_remote_mode);
524 EXPECT_TRUE(options_.do_broadcast);
525
526 // Other options retain default values
527 EXPECT_FALSE(options_.do_add_date);
528 EXPECT_FALSE(options_.do_zip_file);
529 EXPECT_EQ("", options_.use_outfile);
530 EXPECT_FALSE(options_.use_socket);
531 EXPECT_FALSE(options_.use_control_socket);
532}
533
534TEST_F(DumpOptionsTest, InitializeHelp) {
535 // clang-format off
536 char* argv[] = {
537 const_cast<char*>("dumpstate"),
538 const_cast<char*>("-h")
539 };
540 // clang-format on
541
542 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
543
544 // -h is for help.
545 EXPECT_EQ(status, Dumpstate::RunStatus::HELP);
546}
547
548TEST_F(DumpOptionsTest, InitializeUnknown) {
549 // clang-format off
550 char* argv[] = {
551 const_cast<char*>("dumpstate"),
552 const_cast<char*>("-u") // unknown flag
553 };
554 // clang-format on
555
556 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
557
558 // -u is unknown.
559 EXPECT_EQ(status, Dumpstate::RunStatus::INVALID_INPUT);
560}
561
562TEST_F(DumpOptionsTest, ValidateOptionsNeedOutfile1) {
563 options_.do_zip_file = true;
564 EXPECT_FALSE(options_.ValidateOptions());
565 options_.use_outfile = "a/b/c";
566 EXPECT_TRUE(options_.ValidateOptions());
567}
568
569TEST_F(DumpOptionsTest, ValidateOptionsNeedOutfile2) {
570 options_.do_broadcast = true;
571 EXPECT_FALSE(options_.ValidateOptions());
572 options_.use_outfile = "a/b/c";
573 EXPECT_TRUE(options_.ValidateOptions());
574}
575
576TEST_F(DumpOptionsTest, ValidateOptionsNeedZipfile) {
577 options_.use_control_socket = true;
578 EXPECT_FALSE(options_.ValidateOptions());
579
580 options_.do_zip_file = true;
581 options_.use_outfile = "a/b/c"; // do_zip_file needs outfile
582 EXPECT_TRUE(options_.ValidateOptions());
583}
584
585TEST_F(DumpOptionsTest, ValidateOptionsUpdateProgressNeedsBroadcast) {
586 options_.do_progress_updates = true;
587 options_.use_outfile = "a/b/c"; // do_progress_updates needs outfile
588 EXPECT_FALSE(options_.ValidateOptions());
589
590 options_.do_broadcast = true;
591 EXPECT_TRUE(options_.ValidateOptions());
592}
593
594TEST_F(DumpOptionsTest, ValidateOptionsRemoteMode) {
595 options_.is_remote_mode = true;
596 EXPECT_FALSE(options_.ValidateOptions());
597
598 options_.do_broadcast = true;
599 options_.do_zip_file = true;
600 options_.do_add_date = true;
601 options_.use_outfile = "a/b/c"; // do_broadcast needs outfile
602 EXPECT_TRUE(options_.ValidateOptions());
603}
604
Felipe Leme7447d7c2016-11-03 18:12:22 -0700605class DumpstateTest : public DumpstateBaseTest {
Felipe Leme4c2d6632016-09-28 14:32:00 -0700606 public:
607 void SetUp() {
Felipe Leme46b85da2016-11-21 17:40:45 -0800608 DumpstateBaseTest::SetUp();
Felipe Leme4c2d6632016-09-28 14:32:00 -0700609 SetDryRun(false);
Felipe Lemed80e6b62016-10-03 13:08:14 -0700610 SetBuildType(android::base::GetProperty("ro.build.type", "(unknown)"));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700611 ds.progress_.reset(new Progress());
Felipe Leme009ecbb2016-11-07 10:18:44 -0800612 ds.update_progress_threshold_ = 0;
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100613 ds.options_.reset(new Dumpstate::DumpOptions());
Felipe Leme4c2d6632016-09-28 14:32:00 -0700614 }
615
616 // Runs a command and capture `stdout` and `stderr`.
Felipe Leme9a523ae2016-10-20 15:10:33 -0700617 int RunCommand(const std::string& title, const std::vector<std::string>& full_command,
Felipe Leme4c2d6632016-09-28 14:32:00 -0700618 const CommandOptions& options = CommandOptions::DEFAULT) {
619 CaptureStdout();
620 CaptureStderr();
Felipe Leme9a523ae2016-10-20 15:10:33 -0700621 int status = ds.RunCommand(title, full_command, options);
Felipe Leme4c2d6632016-09-28 14:32:00 -0700622 out = GetCapturedStdout();
623 err = GetCapturedStderr();
624 return status;
625 }
626
Felipe Lemecef02982016-10-03 17:22:22 -0700627 // Dumps a file and capture `stdout` and `stderr`.
628 int DumpFile(const std::string& title, const std::string& path) {
629 CaptureStdout();
630 CaptureStderr();
631 int status = ds.DumpFile(title, path);
632 out = GetCapturedStdout();
633 err = GetCapturedStderr();
634 return status;
635 }
636
Felipe Leme009ecbb2016-11-07 10:18:44 -0800637 void SetProgress(long progress, long initial_max, long threshold = 0) {
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100638 ds.options_->do_progress_updates = true;
Felipe Leme009ecbb2016-11-07 10:18:44 -0800639 ds.update_progress_threshold_ = threshold;
640 ds.last_updated_progress_ = 0;
Felipe Leme7447d7c2016-11-03 18:12:22 -0700641 ds.progress_.reset(new Progress(initial_max, progress, 1.2));
642 }
643
Felipe Leme7447d7c2016-11-03 18:12:22 -0700644 std::string GetProgressMessage(const std::string& listener_name, int progress, int max,
Felipe Leme009ecbb2016-11-07 10:18:44 -0800645 int old_max = 0, bool update_progress = true) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700646 EXPECT_EQ(progress, ds.progress_->Get()) << "invalid progress";
647 EXPECT_EQ(max, ds.progress_->GetMax()) << "invalid max";
Felipe Leme75876a22016-10-27 16:31:27 -0700648
Felipe Leme7447d7c2016-11-03 18:12:22 -0700649 bool max_increased = old_max > 0;
Felipe Leme75876a22016-10-27 16:31:27 -0700650
Felipe Leme009ecbb2016-11-07 10:18:44 -0800651 std::string message = "";
Felipe Leme75876a22016-10-27 16:31:27 -0700652 if (max_increased) {
Felipe Leme009ecbb2016-11-07 10:18:44 -0800653 message =
Felipe Leme7447d7c2016-11-03 18:12:22 -0700654 android::base::StringPrintf("Adjusting max progress from %d to %d\n", old_max, max);
Felipe Leme75876a22016-10-27 16:31:27 -0700655 }
656
Felipe Leme009ecbb2016-11-07 10:18:44 -0800657 if (update_progress) {
Nandana Duttbabf6c72019-01-15 14:11:12 +0000658 message += android::base::StringPrintf("Setting progress (%s): %d/%d (%d%%)\n",
659 listener_name.c_str(), progress, max,
660 (100 * progress / max));
Felipe Leme009ecbb2016-11-07 10:18:44 -0800661 }
662
663 return message;
Felipe Lemed80e6b62016-10-03 13:08:14 -0700664 }
665
Felipe Leme4c2d6632016-09-28 14:32:00 -0700666 // `stdout` and `stderr` from the last command ran.
667 std::string out, err;
668
Felipe Lemefd8affa2016-09-30 17:38:57 -0700669 Dumpstate& ds = Dumpstate::GetInstance();
Felipe Leme4c2d6632016-09-28 14:32:00 -0700670};
671
672TEST_F(DumpstateTest, RunCommandNoArgs) {
673 EXPECT_EQ(-1, RunCommand("", {}));
674}
675
676TEST_F(DumpstateTest, RunCommandNoTitle) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700677 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700678 EXPECT_THAT(out, StrEq("stdout\n"));
679 EXPECT_THAT(err, StrEq("stderr\n"));
680}
681
682TEST_F(DumpstateTest, RunCommandWithTitle) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700683 EXPECT_EQ(0, RunCommand("I AM GROOT", {kSimpleCommand}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700684 EXPECT_THAT(err, StrEq("stderr\n"));
685 // We don't know the exact duration, so we check the prefix and suffix
Felipe Lemefd8affa2016-09-30 17:38:57 -0700686 EXPECT_THAT(out,
Felipe Leme7447d7c2016-11-03 18:12:22 -0700687 StartsWith("------ I AM GROOT (" + kSimpleCommand + ") ------\nstdout\n------"));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700688 EXPECT_THAT(out, EndsWith("s was the duration of 'I AM GROOT' ------\n"));
689}
690
Felipe Lemefd8affa2016-09-30 17:38:57 -0700691TEST_F(DumpstateTest, RunCommandWithLoggingMessage) {
Felipe Leme4c2d6632016-09-28 14:32:00 -0700692 EXPECT_EQ(
Felipe Leme7447d7c2016-11-03 18:12:22 -0700693 0, RunCommand("", {kSimpleCommand},
Felipe Lemefd8affa2016-09-30 17:38:57 -0700694 CommandOptions::WithTimeout(10).Log("COMMAND, Y U NO LOG FIRST?").Build()));
695 EXPECT_THAT(out, StrEq("stdout\n"));
696 EXPECT_THAT(err, StrEq("COMMAND, Y U NO LOG FIRST?stderr\n"));
697}
698
699TEST_F(DumpstateTest, RunCommandRedirectStderr) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700700 EXPECT_EQ(0, RunCommand("", {kSimpleCommand},
Felipe Lemefd8affa2016-09-30 17:38:57 -0700701 CommandOptions::WithTimeout(10).RedirectStderr().Build()));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700702 EXPECT_THAT(out, IsEmpty());
Felipe Lemefd8affa2016-09-30 17:38:57 -0700703 EXPECT_THAT(err, StrEq("stdout\nstderr\n"));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700704}
705
706TEST_F(DumpstateTest, RunCommandWithOneArg) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700707 EXPECT_EQ(0, RunCommand("", {kEchoCommand, "one"}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700708 EXPECT_THAT(err, IsEmpty());
709 EXPECT_THAT(out, StrEq("one\n"));
710}
711
Felipe Lemefd8affa2016-09-30 17:38:57 -0700712TEST_F(DumpstateTest, RunCommandWithMultipleArgs) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700713 EXPECT_EQ(0, RunCommand("", {kEchoCommand, "one", "is", "the", "loniest", "number"}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700714 EXPECT_THAT(err, IsEmpty());
715 EXPECT_THAT(out, StrEq("one is the loniest number\n"));
716}
717
718TEST_F(DumpstateTest, RunCommandDryRun) {
719 SetDryRun(true);
Felipe Leme7447d7c2016-11-03 18:12:22 -0700720 EXPECT_EQ(0, RunCommand("I AM GROOT", {kSimpleCommand}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700721 // We don't know the exact duration, so we check the prefix and suffix
Felipe Leme7447d7c2016-11-03 18:12:22 -0700722 EXPECT_THAT(out, StartsWith("------ I AM GROOT (" + kSimpleCommand +
Felipe Leme4c2d6632016-09-28 14:32:00 -0700723 ") ------\n\t(skipped on dry run)\n------"));
724 EXPECT_THAT(out, EndsWith("s was the duration of 'I AM GROOT' ------\n"));
725 EXPECT_THAT(err, IsEmpty());
726}
727
728TEST_F(DumpstateTest, RunCommandDryRunNoTitle) {
729 SetDryRun(true);
Felipe Leme7447d7c2016-11-03 18:12:22 -0700730 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700731 EXPECT_THAT(out, IsEmpty());
732 EXPECT_THAT(err, IsEmpty());
733}
734
735TEST_F(DumpstateTest, RunCommandDryRunAlways) {
736 SetDryRun(true);
Felipe Leme7447d7c2016-11-03 18:12:22 -0700737 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(10).Always().Build()));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700738 EXPECT_THAT(out, StrEq("stdout\n"));
739 EXPECT_THAT(err, StrEq("stderr\n"));
740}
741
Felipe Lemefd8affa2016-09-30 17:38:57 -0700742TEST_F(DumpstateTest, RunCommandNotFound) {
743 EXPECT_NE(0, RunCommand("", {"/there/cannot/be/such/command"}));
744 EXPECT_THAT(out, StartsWith("*** command '/there/cannot/be/such/command' failed: exit code"));
745 EXPECT_THAT(err, StartsWith("execvp on command '/there/cannot/be/such/command' failed"));
746}
747
748TEST_F(DumpstateTest, RunCommandFails) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700749 EXPECT_EQ(42, RunCommand("", {kSimpleCommand, "--exit", "42"}));
750 EXPECT_THAT(out, StrEq("stdout\n*** command '" + kSimpleCommand +
Felipe Leme9a523ae2016-10-20 15:10:33 -0700751 " --exit 42' failed: exit code 42\n"));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700752 EXPECT_THAT(err, StrEq("stderr\n*** command '" + kSimpleCommand +
Felipe Leme9a523ae2016-10-20 15:10:33 -0700753 " --exit 42' failed: exit code 42\n"));
Felipe Lemefd8affa2016-09-30 17:38:57 -0700754}
755
756TEST_F(DumpstateTest, RunCommandCrashes) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700757 EXPECT_NE(0, RunCommand("", {kSimpleCommand, "--crash"}));
Felipe Lemefd8affa2016-09-30 17:38:57 -0700758 // We don't know the exit code, so check just the prefix.
759 EXPECT_THAT(
Felipe Leme7447d7c2016-11-03 18:12:22 -0700760 out, StartsWith("stdout\n*** command '" + kSimpleCommand + " --crash' failed: exit code"));
Felipe Lemefd8affa2016-09-30 17:38:57 -0700761 EXPECT_THAT(
Felipe Leme7447d7c2016-11-03 18:12:22 -0700762 err, StartsWith("stderr\n*** command '" + kSimpleCommand + " --crash' failed: exit code"));
Felipe Lemefd8affa2016-09-30 17:38:57 -0700763}
764
765TEST_F(DumpstateTest, RunCommandTimesout) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700766 EXPECT_EQ(-1, RunCommand("", {kSimpleCommand, "--sleep", "2"},
Felipe Lemefd8affa2016-09-30 17:38:57 -0700767 CommandOptions::WithTimeout(1).Build()));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700768 EXPECT_THAT(out, StartsWith("stdout line1\n*** command '" + kSimpleCommand +
Felipe Lemefd8affa2016-09-30 17:38:57 -0700769 " --sleep 2' timed out after 1"));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700770 EXPECT_THAT(err, StartsWith("sleeping for 2s\n*** command '" + kSimpleCommand +
Felipe Lemefd8affa2016-09-30 17:38:57 -0700771 " --sleep 2' timed out after 1"));
772}
773
774TEST_F(DumpstateTest, RunCommandIsKilled) {
775 CaptureStdout();
776 CaptureStderr();
777
778 std::thread t([=]() {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700779 EXPECT_EQ(SIGTERM, ds.RunCommand("", {kSimpleCommand, "--pid", "--sleep", "20"},
Felipe Lemefd8affa2016-09-30 17:38:57 -0700780 CommandOptions::WithTimeout(100).Always().Build()));
781 });
782
783 // Capture pid and pre-sleep output.
784 sleep(1); // Wait a little bit to make sure pid and 1st line were printed.
785 std::string err = GetCapturedStderr();
786 EXPECT_THAT(err, StrEq("sleeping for 20s\n"));
787
788 std::string out = GetCapturedStdout();
789 std::vector<std::string> lines = android::base::Split(out, "\n");
790 ASSERT_EQ(3, (int)lines.size()) << "Invalid lines before sleep: " << out;
791
792 int pid = atoi(lines[0].c_str());
793 EXPECT_THAT(lines[1], StrEq("stdout line1"));
794 EXPECT_THAT(lines[2], IsEmpty()); // \n
795
796 // Then kill the process.
797 CaptureStdout();
798 CaptureStderr();
799 ASSERT_EQ(0, kill(pid, SIGTERM)) << "failed to kill pid " << pid;
800 t.join();
801
802 // Finally, check output after murder.
803 out = GetCapturedStdout();
804 err = GetCapturedStderr();
805
Felipe Leme7447d7c2016-11-03 18:12:22 -0700806 EXPECT_THAT(out, StrEq("*** command '" + kSimpleCommand +
Felipe Lemefd8affa2016-09-30 17:38:57 -0700807 " --pid --sleep 20' failed: killed by signal 15\n"));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700808 EXPECT_THAT(err, StrEq("*** command '" + kSimpleCommand +
Felipe Lemefd8affa2016-09-30 17:38:57 -0700809 " --pid --sleep 20' failed: killed by signal 15\n"));
810}
811
Felipe Leme75876a22016-10-27 16:31:27 -0700812TEST_F(DumpstateTest, RunCommandProgress) {
813 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
814 ds.listener_ = listener;
815 ds.listener_name_ = "FoxMulder";
Felipe Leme7447d7c2016-11-03 18:12:22 -0700816 SetProgress(0, 30);
Felipe Leme75876a22016-10-27 16:31:27 -0700817
818 EXPECT_CALL(*listener, onProgressUpdated(20));
Nandana Duttbabf6c72019-01-15 14:11:12 +0000819 EXPECT_CALL(*listener, onProgress(66)); // 20/30 %
Felipe Leme7447d7c2016-11-03 18:12:22 -0700820 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(20).Build()));
Felipe Leme75876a22016-10-27 16:31:27 -0700821 std::string progress_message = GetProgressMessage(ds.listener_name_, 20, 30);
822 EXPECT_THAT(out, StrEq("stdout\n"));
823 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
824
825 EXPECT_CALL(*listener, onProgressUpdated(30));
Nandana Duttbabf6c72019-01-15 14:11:12 +0000826 EXPECT_CALL(*listener, onProgress(100)); // 35/35 %
Felipe Leme7447d7c2016-11-03 18:12:22 -0700827 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(10).Build()));
Felipe Leme75876a22016-10-27 16:31:27 -0700828 progress_message = GetProgressMessage(ds.listener_name_, 30, 30);
829 EXPECT_THAT(out, StrEq("stdout\n"));
830 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
831
832 // Run a command that will increase maximum timeout.
833 EXPECT_CALL(*listener, onProgressUpdated(31));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700834 EXPECT_CALL(*listener, onMaxProgressUpdated(37));
Nandana Duttbabf6c72019-01-15 14:11:12 +0000835 EXPECT_CALL(*listener, onProgress(83)); // 31/37 %
Felipe Leme7447d7c2016-11-03 18:12:22 -0700836 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).Build()));
837 progress_message = GetProgressMessage(ds.listener_name_, 31, 37, 30); // 20% increase
Felipe Leme75876a22016-10-27 16:31:27 -0700838 EXPECT_THAT(out, StrEq("stdout\n"));
839 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
840
841 // Make sure command ran while in dry_run is counted.
842 SetDryRun(true);
843 EXPECT_CALL(*listener, onProgressUpdated(35));
Nandana Duttbabf6c72019-01-15 14:11:12 +0000844 EXPECT_CALL(*listener, onProgress(94)); // 35/37 %
Felipe Leme7447d7c2016-11-03 18:12:22 -0700845 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(4).Build()));
846 progress_message = GetProgressMessage(ds.listener_name_, 35, 37);
Felipe Leme75876a22016-10-27 16:31:27 -0700847 EXPECT_THAT(out, IsEmpty());
848 EXPECT_THAT(err, StrEq(progress_message));
849
850 ds.listener_.clear();
851}
852
Felipe Leme009ecbb2016-11-07 10:18:44 -0800853TEST_F(DumpstateTest, RunCommandProgressIgnoreThreshold) {
854 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
855 ds.listener_ = listener;
856 ds.listener_name_ = "FoxMulder";
857 SetProgress(0, 8, 5); // 8 max, 5 threshold
858
859 // First update should always be sent.
860 EXPECT_CALL(*listener, onProgressUpdated(1));
Nandana Duttbabf6c72019-01-15 14:11:12 +0000861 EXPECT_CALL(*listener, onProgress(12)); // 1/12 %
Felipe Leme009ecbb2016-11-07 10:18:44 -0800862 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).Build()));
863 std::string progress_message = GetProgressMessage(ds.listener_name_, 1, 8);
864 EXPECT_THAT(out, StrEq("stdout\n"));
865 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
866
867 // Fourth update should be ignored because it's between the threshold (5 -1 = 4 < 5).
868 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(4).Build()));
869 EXPECT_THAT(out, StrEq("stdout\n"));
870 EXPECT_THAT(err, StrEq("stderr\n"));
871
872 // Third update should be sent because it reaches threshold (6 - 1 = 5).
873 EXPECT_CALL(*listener, onProgressUpdated(6));
Nandana Duttbabf6c72019-01-15 14:11:12 +0000874 EXPECT_CALL(*listener, onProgress(75)); // 6/8 %
Felipe Leme009ecbb2016-11-07 10:18:44 -0800875 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).Build()));
876 progress_message = GetProgressMessage(ds.listener_name_, 6, 8);
877 EXPECT_THAT(out, StrEq("stdout\n"));
878 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
879
880 // Fourth update should be ignored because it's between the threshold (9 - 6 = 3 < 5).
881 // But max update should be sent.
882 EXPECT_CALL(*listener, onMaxProgressUpdated(10)); // 9 * 120% = 10.8 = 10
883 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(3).Build()));
884 progress_message = GetProgressMessage(ds.listener_name_, 9, 10, 8, false);
885 EXPECT_THAT(out, StrEq("stdout\n"));
886 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
887
888 ds.listener_.clear();
889}
890
Felipe Lemed80e6b62016-10-03 13:08:14 -0700891TEST_F(DumpstateTest, RunCommandDropRoot) {
Felipe Leme46b85da2016-11-21 17:40:45 -0800892 if (!IsStandalone()) {
893 // TODO: temporarily disabled because it might cause other tests to fail after dropping
894 // to Shell - need to refactor tests to avoid this problem)
895 MYLOGE("Skipping DumpstateTest.RunCommandDropRoot() on test suite\n")
896 return;
897 }
Felipe Lemed80e6b62016-10-03 13:08:14 -0700898 // First check root case - only available when running with 'adb root'.
899 uid_t uid = getuid();
900 if (uid == 0) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700901 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"}));
Felipe Lemed80e6b62016-10-03 13:08:14 -0700902 EXPECT_THAT(out, StrEq("0\nstdout\n"));
903 EXPECT_THAT(err, StrEq("stderr\n"));
904 return;
905 }
Felipe Leme7447d7c2016-11-03 18:12:22 -0700906 // Then run dropping root.
907 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
Felipe Lemed80e6b62016-10-03 13:08:14 -0700908 CommandOptions::WithTimeout(1).DropRoot().Build()));
909 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
Felipe Leme26c41572016-10-06 14:34:43 -0700910 EXPECT_THAT(err, StrEq("drop_root_user(): already running as Shell\nstderr\n"));
Felipe Lemed80e6b62016-10-03 13:08:14 -0700911}
912
913TEST_F(DumpstateTest, RunCommandAsRootUserBuild) {
Felipe Leme46b85da2016-11-21 17:40:45 -0800914 if (!IsStandalone()) {
915 // TODO: temporarily disabled because it might cause other tests to fail after dropping
916 // to Shell - need to refactor tests to avoid this problem)
917 MYLOGE("Skipping DumpstateTest.RunCommandAsRootUserBuild() on test suite\n")
918 return;
919 }
Felipe Lemef0292972016-11-22 13:57:05 -0800920 if (!PropertiesHelper::IsUserBuild()) {
Felipe Lemed80e6b62016-10-03 13:08:14 -0700921 // Emulates user build if necessarily.
922 SetBuildType("user");
923 }
924
925 DropRoot();
926
Felipe Leme7447d7c2016-11-03 18:12:22 -0700927 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).AsRoot().Build()));
Felipe Lemed80e6b62016-10-03 13:08:14 -0700928
929 // We don't know the exact path of su, so we just check for the 'root ...' commands
930 EXPECT_THAT(out, StartsWith("Skipping"));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700931 EXPECT_THAT(out, EndsWith("root " + kSimpleCommand + "' on user build.\n"));
Felipe Lemed80e6b62016-10-03 13:08:14 -0700932 EXPECT_THAT(err, IsEmpty());
933}
934
Felipe Leme46b85da2016-11-21 17:40:45 -0800935TEST_F(DumpstateTest, RunCommandAsRootNonUserBuild) {
936 if (!IsStandalone()) {
937 // TODO: temporarily disabled because it might cause other tests to fail after dropping
938 // to Shell - need to refactor tests to avoid this problem)
939 MYLOGE("Skipping DumpstateTest.RunCommandAsRootNonUserBuild() on test suite\n")
940 return;
941 }
Felipe Lemef0292972016-11-22 13:57:05 -0800942 if (PropertiesHelper::IsUserBuild()) {
Felipe Leme46b85da2016-11-21 17:40:45 -0800943 ALOGI("Skipping RunCommandAsRootNonUserBuild on user builds\n");
944 return;
945 }
946
947 DropRoot();
948
949 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
950 CommandOptions::WithTimeout(1).AsRoot().Build()));
951
952 EXPECT_THAT(out, StrEq("0\nstdout\n"));
953 EXPECT_THAT(err, StrEq("stderr\n"));
954}
955
Nandana Dutt4b392be2018-11-02 16:17:05 +0000956TEST_F(DumpstateTest, RunCommandAsRootNonUserBuild_withUnroot) {
957 if (!IsStandalone()) {
958 // TODO: temporarily disabled because it might cause other tests to fail after dropping
959 // to Shell - need to refactor tests to avoid this problem)
960 MYLOGE(
961 "Skipping DumpstateTest.RunCommandAsRootNonUserBuild_withUnroot() "
962 "on test suite\n")
963 return;
964 }
965 if (PropertiesHelper::IsUserBuild()) {
966 ALOGI("Skipping RunCommandAsRootNonUserBuild_withUnroot on user builds\n");
967 return;
968 }
969
970 // Same test as above, but with unroot property set, which will override su availability.
971 SetUnroot(true);
972 DropRoot();
973
974 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
975 CommandOptions::WithTimeout(1).AsRoot().Build()));
976
977 // AsRoot is ineffective.
978 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
979 EXPECT_THAT(err, StrEq("drop_root_user(): already running as Shell\nstderr\n"));
980}
981
Yifan Hong48e83a12017-10-03 14:10:07 -0700982TEST_F(DumpstateTest, RunCommandAsRootIfAvailableOnUserBuild) {
983 if (!IsStandalone()) {
984 // TODO: temporarily disabled because it might cause other tests to fail after dropping
985 // to Shell - need to refactor tests to avoid this problem)
986 MYLOGE("Skipping DumpstateTest.RunCommandAsRootIfAvailableOnUserBuild() on test suite\n")
987 return;
988 }
989 if (!PropertiesHelper::IsUserBuild()) {
990 // Emulates user build if necessarily.
991 SetBuildType("user");
992 }
993
994 DropRoot();
995
996 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
997 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
998
999 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
1000 EXPECT_THAT(err, StrEq("stderr\n"));
1001}
1002
1003TEST_F(DumpstateTest, RunCommandAsRootIfAvailableOnDebugBuild) {
1004 if (!IsStandalone()) {
1005 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1006 // to Shell - need to refactor tests to avoid this problem)
1007 MYLOGE("Skipping DumpstateTest.RunCommandAsRootIfAvailableOnDebugBuild() on test suite\n")
1008 return;
1009 }
1010 if (PropertiesHelper::IsUserBuild()) {
1011 ALOGI("Skipping RunCommandAsRootNonUserBuild on user builds\n");
1012 return;
1013 }
1014
1015 DropRoot();
1016
1017 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
1018 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
1019
1020 EXPECT_THAT(out, StrEq("0\nstdout\n"));
1021 EXPECT_THAT(err, StrEq("stderr\n"));
1022}
1023
Nandana Dutt4b392be2018-11-02 16:17:05 +00001024TEST_F(DumpstateTest, RunCommandAsRootIfAvailableOnDebugBuild_withUnroot) {
1025 if (!IsStandalone()) {
1026 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1027 // to Shell - need to refactor tests to avoid this problem)
1028 MYLOGE(
1029 "Skipping DumpstateTest.RunCommandAsRootIfAvailableOnDebugBuild_withUnroot() "
1030 "on test suite\n")
1031 return;
1032 }
1033 if (PropertiesHelper::IsUserBuild()) {
1034 ALOGI("Skipping RunCommandAsRootIfAvailableOnDebugBuild_withUnroot on user builds\n");
1035 return;
1036 }
1037 // Same test as above, but with unroot property set, which will override su availability.
1038 SetUnroot(true);
1039
1040 DropRoot();
1041
1042 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
1043 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
1044
1045 // It's a userdebug build, so "su root" should be available, but unroot=true overrides it.
1046 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
1047 EXPECT_THAT(err, StrEq("stderr\n"));
1048}
1049
Felipe Lemecef02982016-10-03 17:22:22 -07001050TEST_F(DumpstateTest, DumpFileNotFoundNoTitle) {
1051 EXPECT_EQ(-1, DumpFile("", "/I/cant/believe/I/exist"));
1052 EXPECT_THAT(out,
1053 StrEq("*** Error dumping /I/cant/believe/I/exist: No such file or directory\n"));
1054 EXPECT_THAT(err, IsEmpty());
1055}
1056
1057TEST_F(DumpstateTest, DumpFileNotFoundWithTitle) {
1058 EXPECT_EQ(-1, DumpFile("Y U NO EXIST?", "/I/cant/believe/I/exist"));
1059 EXPECT_THAT(err, IsEmpty());
1060 // We don't know the exact duration, so we check the prefix and suffix
1061 EXPECT_THAT(out, StartsWith("*** Error dumping /I/cant/believe/I/exist (Y U NO EXIST?): No "
1062 "such file or directory\n"));
1063 EXPECT_THAT(out, EndsWith("s was the duration of 'Y U NO EXIST?' ------\n"));
1064}
1065
1066TEST_F(DumpstateTest, DumpFileSingleLine) {
Felipe Leme7447d7c2016-11-03 18:12:22 -07001067 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -07001068 EXPECT_THAT(err, IsEmpty());
1069 EXPECT_THAT(out, StrEq("I AM LINE1\n")); // dumpstate adds missing newline
1070}
1071
1072TEST_F(DumpstateTest, DumpFileSingleLineWithNewLine) {
Felipe Leme7447d7c2016-11-03 18:12:22 -07001073 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line-with-newline.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -07001074 EXPECT_THAT(err, IsEmpty());
1075 EXPECT_THAT(out, StrEq("I AM LINE1\n"));
1076}
1077
1078TEST_F(DumpstateTest, DumpFileMultipleLines) {
Felipe Leme7447d7c2016-11-03 18:12:22 -07001079 EXPECT_EQ(0, DumpFile("", kTestDataPath + "multiple-lines.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -07001080 EXPECT_THAT(err, IsEmpty());
1081 EXPECT_THAT(out, StrEq("I AM LINE1\nI AM LINE2\nI AM LINE3\n"));
1082}
1083
1084TEST_F(DumpstateTest, DumpFileMultipleLinesWithNewLine) {
Felipe Leme7447d7c2016-11-03 18:12:22 -07001085 EXPECT_EQ(0, DumpFile("", kTestDataPath + "multiple-lines-with-newline.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -07001086 EXPECT_THAT(err, IsEmpty());
1087 EXPECT_THAT(out, StrEq("I AM LINE1\nI AM LINE2\nI AM LINE3\n"));
1088}
1089
1090TEST_F(DumpstateTest, DumpFileOnDryRunNoTitle) {
1091 SetDryRun(true);
Felipe Leme7447d7c2016-11-03 18:12:22 -07001092 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -07001093 EXPECT_THAT(err, IsEmpty());
1094 EXPECT_THAT(out, IsEmpty());
1095}
1096
1097TEST_F(DumpstateTest, DumpFileOnDryRun) {
1098 SetDryRun(true);
Felipe Leme7447d7c2016-11-03 18:12:22 -07001099 EXPECT_EQ(0, DumpFile("Might as well dump. Dump!", kTestDataPath + "single-line.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -07001100 EXPECT_THAT(err, IsEmpty());
Felipe Leme46b85da2016-11-21 17:40:45 -08001101 EXPECT_THAT(
1102 out, StartsWith("------ Might as well dump. Dump! (" + kTestDataPath + "single-line.txt:"));
1103 EXPECT_THAT(out, HasSubstr("\n\t(skipped on dry run)\n------"));
Felipe Lemecef02982016-10-03 17:22:22 -07001104 EXPECT_THAT(out, EndsWith("s was the duration of 'Might as well dump. Dump!' ------\n"));
Felipe Lemecef02982016-10-03 17:22:22 -07001105}
1106
Felipe Leme75876a22016-10-27 16:31:27 -07001107TEST_F(DumpstateTest, DumpFileUpdateProgress) {
1108 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
1109 ds.listener_ = listener;
1110 ds.listener_name_ = "FoxMulder";
Felipe Leme7447d7c2016-11-03 18:12:22 -07001111 SetProgress(0, 30);
Felipe Leme75876a22016-10-27 16:31:27 -07001112
1113 EXPECT_CALL(*listener, onProgressUpdated(5));
Nandana Duttbabf6c72019-01-15 14:11:12 +00001114 EXPECT_CALL(*listener, onProgress(16)); // 5/30 %
Felipe Leme7447d7c2016-11-03 18:12:22 -07001115 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
Felipe Leme75876a22016-10-27 16:31:27 -07001116
1117 std::string progress_message =
1118 GetProgressMessage(ds.listener_name_, 5, 30); // TODO: unhardcode WEIGHT_FILE (5)?
1119 EXPECT_THAT(err, StrEq(progress_message));
1120 EXPECT_THAT(out, StrEq("I AM LINE1\n")); // dumpstate adds missing newline
1121
1122 ds.listener_.clear();
1123}
1124
Felipe Leme7447d7c2016-11-03 18:12:22 -07001125class DumpstateServiceTest : public DumpstateBaseTest {
Felipe Leme75876a22016-10-27 16:31:27 -07001126 public:
1127 DumpstateService dss;
1128};
1129
1130TEST_F(DumpstateServiceTest, SetListenerNoName) {
1131 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
Felipe Leme009ecbb2016-11-07 10:18:44 -08001132 sp<IDumpstateToken> token;
Vishnu Nair20cf5032018-01-05 13:15:49 -08001133 EXPECT_TRUE(dss.setListener("", listener, /* getSectionDetails = */ false, &token).isOk());
Felipe Leme009ecbb2016-11-07 10:18:44 -08001134 ASSERT_THAT(token, IsNull());
Felipe Leme75876a22016-10-27 16:31:27 -07001135}
1136
1137TEST_F(DumpstateServiceTest, SetListenerNoPointer) {
Felipe Leme009ecbb2016-11-07 10:18:44 -08001138 sp<IDumpstateToken> token;
Vishnu Nair20cf5032018-01-05 13:15:49 -08001139 EXPECT_TRUE(
1140 dss.setListener("whatever", nullptr, /* getSectionDetails = */ false, &token).isOk());
Felipe Leme009ecbb2016-11-07 10:18:44 -08001141 ASSERT_THAT(token, IsNull());
Felipe Leme75876a22016-10-27 16:31:27 -07001142}
1143
1144TEST_F(DumpstateServiceTest, SetListenerTwice) {
1145 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
Felipe Leme009ecbb2016-11-07 10:18:44 -08001146 sp<IDumpstateToken> token;
Vishnu Nair20cf5032018-01-05 13:15:49 -08001147 EXPECT_TRUE(
1148 dss.setListener("whatever", listener, /* getSectionDetails = */ false, &token).isOk());
Felipe Leme009ecbb2016-11-07 10:18:44 -08001149 ASSERT_THAT(token, NotNull());
Felipe Leme75876a22016-10-27 16:31:27 -07001150 EXPECT_THAT(Dumpstate::GetInstance().listener_name_, StrEq("whatever"));
Vishnu Nair20cf5032018-01-05 13:15:49 -08001151 EXPECT_FALSE(Dumpstate::GetInstance().report_section_);
Felipe Leme75876a22016-10-27 16:31:27 -07001152
Felipe Leme009ecbb2016-11-07 10:18:44 -08001153 token.clear();
Vishnu Nair20cf5032018-01-05 13:15:49 -08001154 EXPECT_TRUE(
1155 dss.setListener("whatsoever", listener, /* getSectionDetails = */ false, &token).isOk());
Felipe Leme009ecbb2016-11-07 10:18:44 -08001156 ASSERT_THAT(token, IsNull());
1157 EXPECT_THAT(Dumpstate::GetInstance().listener_name_, StrEq("whatever"));
Vishnu Nair20cf5032018-01-05 13:15:49 -08001158 EXPECT_FALSE(Dumpstate::GetInstance().report_section_);
1159}
1160
1161TEST_F(DumpstateServiceTest, SetListenerWithSectionDetails) {
1162 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
1163 sp<IDumpstateToken> token;
1164 Dumpstate::GetInstance().listener_ = nullptr;
1165 EXPECT_TRUE(
1166 dss.setListener("whatever", listener, /* getSectionDetails = */ true, &token).isOk());
1167 ASSERT_THAT(token, NotNull());
1168 EXPECT_THAT(Dumpstate::GetInstance().listener_name_, StrEq("whatever"));
1169 EXPECT_TRUE(Dumpstate::GetInstance().report_section_);
Felipe Leme75876a22016-10-27 16:31:27 -07001170}
Felipe Leme7447d7c2016-11-03 18:12:22 -07001171
1172class ProgressTest : public DumpstateBaseTest {
1173 public:
1174 Progress GetInstance(int32_t max, double growth_factor, const std::string& path = "") {
1175 return Progress(max, growth_factor, path);
1176 }
1177
1178 void AssertStats(const std::string& path, int32_t expected_runs, int32_t expected_average) {
1179 std::string expected_content =
1180 android::base::StringPrintf("%d %d\n", expected_runs, expected_average);
1181 std::string actual_content;
Felipe Leme46b85da2016-11-21 17:40:45 -08001182 ReadFileToString(path, &actual_content);
Felipe Leme7447d7c2016-11-03 18:12:22 -07001183 ASSERT_THAT(actual_content, StrEq(expected_content)) << "invalid stats on " << path;
1184 }
1185};
1186
1187TEST_F(ProgressTest, SimpleTest) {
1188 Progress progress;
1189 EXPECT_EQ(0, progress.Get());
1190 EXPECT_EQ(Progress::kDefaultMax, progress.GetInitialMax());
1191 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1192
1193 bool max_increased = progress.Inc(1);
1194 EXPECT_EQ(1, progress.Get());
1195 EXPECT_EQ(Progress::kDefaultMax, progress.GetInitialMax());
1196 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1197 EXPECT_FALSE(max_increased);
1198
1199 // Ignore negative increase.
1200 max_increased = progress.Inc(-1);
1201 EXPECT_EQ(1, progress.Get());
1202 EXPECT_EQ(Progress::kDefaultMax, progress.GetInitialMax());
1203 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1204 EXPECT_FALSE(max_increased);
1205}
1206
1207TEST_F(ProgressTest, MaxGrowsInsideNewRange) {
1208 Progress progress = GetInstance(10, 1.2); // 20% growth factor
1209 EXPECT_EQ(0, progress.Get());
1210 EXPECT_EQ(10, progress.GetInitialMax());
1211 EXPECT_EQ(10, progress.GetMax());
1212
1213 // No increase
1214 bool max_increased = progress.Inc(10);
1215 EXPECT_EQ(10, progress.Get());
1216 EXPECT_EQ(10, progress.GetMax());
1217 EXPECT_FALSE(max_increased);
1218
1219 // Increase, with new value < max*20%
1220 max_increased = progress.Inc(1);
1221 EXPECT_EQ(11, progress.Get());
1222 EXPECT_EQ(13, progress.GetMax()); // 11 average * 20% growth = 13.2 = 13
1223 EXPECT_TRUE(max_increased);
1224}
1225
1226TEST_F(ProgressTest, MaxGrowsOutsideNewRange) {
1227 Progress progress = GetInstance(10, 1.2); // 20% growth factor
1228 EXPECT_EQ(0, progress.Get());
1229 EXPECT_EQ(10, progress.GetInitialMax());
1230 EXPECT_EQ(10, progress.GetMax());
1231
1232 // No increase
1233 bool max_increased = progress.Inc(10);
1234 EXPECT_EQ(10, progress.Get());
1235 EXPECT_EQ(10, progress.GetMax());
1236 EXPECT_FALSE(max_increased);
1237
1238 // Increase, with new value > max*20%
1239 max_increased = progress.Inc(5);
1240 EXPECT_EQ(15, progress.Get());
1241 EXPECT_EQ(18, progress.GetMax()); // 15 average * 20% growth = 18
1242 EXPECT_TRUE(max_increased);
1243}
1244
1245TEST_F(ProgressTest, InvalidPath) {
1246 Progress progress("/devil/null");
1247 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1248}
1249
1250TEST_F(ProgressTest, EmptyFile) {
1251 Progress progress(CopyTextFileFixture("empty-file.txt"));
1252 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1253}
1254
1255TEST_F(ProgressTest, InvalidLine1stEntryNAN) {
1256 Progress progress(CopyTextFileFixture("stats-invalid-1st-NAN.txt"));
1257 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1258}
1259
1260TEST_F(ProgressTest, InvalidLine2ndEntryNAN) {
1261 Progress progress(CopyTextFileFixture("stats-invalid-2nd-NAN.txt"));
1262 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1263}
1264
1265TEST_F(ProgressTest, InvalidLineBothNAN) {
1266 Progress progress(CopyTextFileFixture("stats-invalid-both-NAN.txt"));
1267 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1268}
1269
1270TEST_F(ProgressTest, InvalidLine1stEntryNegative) {
1271 Progress progress(CopyTextFileFixture("stats-invalid-1st-negative.txt"));
1272 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1273}
1274
1275TEST_F(ProgressTest, InvalidLine2ndEntryNegative) {
1276 Progress progress(CopyTextFileFixture("stats-invalid-2nd-negative.txt"));
1277 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1278}
1279
1280TEST_F(ProgressTest, InvalidLine1stEntryTooBig) {
1281 Progress progress(CopyTextFileFixture("stats-invalid-1st-too-big.txt"));
1282 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1283}
1284
1285TEST_F(ProgressTest, InvalidLine2ndEntryTooBig) {
1286 Progress progress(CopyTextFileFixture("stats-invalid-2nd-too-big.txt"));
1287 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1288}
1289
1290// Tests stats are properly saved when the file does not exists.
1291TEST_F(ProgressTest, FirstTime) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001292 if (!IsStandalone()) {
1293 // TODO: temporarily disabled because it's failing when running as suite
1294 MYLOGE("Skipping ProgressTest.FirstTime() on test suite\n")
1295 return;
1296 }
1297
Felipe Leme7447d7c2016-11-03 18:12:22 -07001298 std::string path = kTestDataPath + "FirstTime.txt";
1299 android::base::RemoveFileIfExists(path);
1300
1301 Progress run1(path);
1302 EXPECT_EQ(0, run1.Get());
1303 EXPECT_EQ(Progress::kDefaultMax, run1.GetInitialMax());
1304 EXPECT_EQ(Progress::kDefaultMax, run1.GetMax());
1305
1306 bool max_increased = run1.Inc(20);
1307 EXPECT_EQ(20, run1.Get());
1308 EXPECT_EQ(Progress::kDefaultMax, run1.GetMax());
1309 EXPECT_FALSE(max_increased);
1310
1311 run1.Save();
1312 AssertStats(path, 1, 20);
1313}
1314
1315// Tests what happens when the persistent settings contains the average duration of 1 run.
1316// Data on file is 1 run and 109 average.
1317TEST_F(ProgressTest, SecondTime) {
1318 std::string path = CopyTextFileFixture("stats-one-run-no-newline.txt");
1319
1320 Progress run1 = GetInstance(-42, 1.2, path);
1321 EXPECT_EQ(0, run1.Get());
1322 EXPECT_EQ(10, run1.GetInitialMax());
1323 EXPECT_EQ(10, run1.GetMax());
1324
1325 bool max_increased = run1.Inc(20);
1326 EXPECT_EQ(20, run1.Get());
1327 EXPECT_EQ(24, run1.GetMax());
1328 EXPECT_TRUE(max_increased);
1329
1330 // Average now is 2 runs and (10 + 20)/ 2 = 15
1331 run1.Save();
1332 AssertStats(path, 2, 15);
1333
1334 Progress run2 = GetInstance(-42, 1.2, path);
1335 EXPECT_EQ(0, run2.Get());
1336 EXPECT_EQ(15, run2.GetInitialMax());
1337 EXPECT_EQ(15, run2.GetMax());
1338
1339 max_increased = run2.Inc(25);
1340 EXPECT_EQ(25, run2.Get());
1341 EXPECT_EQ(30, run2.GetMax());
1342 EXPECT_TRUE(max_increased);
1343
1344 // Average now is 3 runs and (15 * 2 + 25)/ 3 = 18.33 = 18
1345 run2.Save();
1346 AssertStats(path, 3, 18);
1347
1348 Progress run3 = GetInstance(-42, 1.2, path);
1349 EXPECT_EQ(0, run3.Get());
1350 EXPECT_EQ(18, run3.GetInitialMax());
1351 EXPECT_EQ(18, run3.GetMax());
1352
1353 // Make sure average decreases as well
1354 max_increased = run3.Inc(5);
1355 EXPECT_EQ(5, run3.Get());
1356 EXPECT_EQ(18, run3.GetMax());
1357 EXPECT_FALSE(max_increased);
1358
1359 // Average now is 4 runs and (18 * 3 + 5)/ 4 = 14.75 = 14
1360 run3.Save();
1361 AssertStats(path, 4, 14);
1362}
1363
1364// Tests what happens when the persistent settings contains the average duration of 2 runs.
1365// Data on file is 2 runs and 15 average.
1366TEST_F(ProgressTest, ThirdTime) {
1367 std::string path = CopyTextFileFixture("stats-two-runs.txt");
1368 AssertStats(path, 2, 15); // Sanity check
1369
1370 Progress run1 = GetInstance(-42, 1.2, path);
1371 EXPECT_EQ(0, run1.Get());
1372 EXPECT_EQ(15, run1.GetInitialMax());
1373 EXPECT_EQ(15, run1.GetMax());
1374
1375 bool max_increased = run1.Inc(20);
1376 EXPECT_EQ(20, run1.Get());
1377 EXPECT_EQ(24, run1.GetMax());
1378 EXPECT_TRUE(max_increased);
1379
1380 // Average now is 3 runs and (15 * 2 + 20)/ 3 = 16.66 = 16
1381 run1.Save();
1382 AssertStats(path, 3, 16);
1383}
1384
Felipe Leme46b85da2016-11-21 17:40:45 -08001385class DumpstateUtilTest : public DumpstateBaseTest {
1386 public:
1387 void SetUp() {
1388 DumpstateBaseTest::SetUp();
1389 SetDryRun(false);
1390 }
1391
Felipe Leme46b85da2016-11-21 17:40:45 -08001392 void CaptureFdOut() {
Felipe Lemef0292972016-11-22 13:57:05 -08001393 ReadFileToString(path_, &out);
Felipe Leme46b85da2016-11-21 17:40:45 -08001394 }
1395
1396 void CreateFd(const std::string& name) {
1397 path_ = kTestDataPath + name;
1398 MYLOGD("Creating fd for file %s\n", path_.c_str());
1399
1400 fd = TEMP_FAILURE_RETRY(open(path_.c_str(),
1401 O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW,
1402 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH));
1403 ASSERT_GE(fd, 0) << "could not create FD for path " << path_;
1404 }
1405
1406 // Runs a command into the `fd` and capture `stderr`.
Felipe Lemef0292972016-11-22 13:57:05 -08001407 int RunCommand(const std::string& title, const std::vector<std::string>& full_command,
Felipe Leme46b85da2016-11-21 17:40:45 -08001408 const CommandOptions& options = CommandOptions::DEFAULT) {
1409 CaptureStderr();
Felipe Lemef0292972016-11-22 13:57:05 -08001410 int status = RunCommandToFd(fd, title, full_command, options);
Felipe Leme46b85da2016-11-21 17:40:45 -08001411 close(fd);
1412
1413 CaptureFdOut();
1414 err = GetCapturedStderr();
1415 return status;
1416 }
1417
1418 // Dumps a file and into the `fd` and `stderr`.
Felipe Lemef0292972016-11-22 13:57:05 -08001419 int DumpFile(const std::string& title, const std::string& path) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001420 CaptureStderr();
Felipe Lemef0292972016-11-22 13:57:05 -08001421 int status = DumpFileToFd(fd, title, path);
Felipe Leme46b85da2016-11-21 17:40:45 -08001422 close(fd);
1423
1424 CaptureFdOut();
1425 err = GetCapturedStderr();
1426 return status;
1427 }
1428
Ecco Park61ffcf72016-10-27 15:46:26 -07001429 // Find out the pid of the process_name
1430 int FindPidOfProcess(const std::string& process_name) {
1431 CaptureStderr();
1432 int status = GetPidByName(process_name);
1433 err = GetCapturedStderr();
1434 return status;
1435 }
1436
Felipe Leme46b85da2016-11-21 17:40:45 -08001437 int fd;
1438
1439 // 'fd` output and `stderr` from the last command ran.
1440 std::string out, err;
1441
1442 private:
1443 std::string path_;
1444};
1445
1446TEST_F(DumpstateUtilTest, RunCommandNoArgs) {
Felipe Lemef0292972016-11-22 13:57:05 -08001447 CreateFd("RunCommandNoArgs.txt");
1448 EXPECT_EQ(-1, RunCommand("", {}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001449}
1450
Felipe Lemef0292972016-11-22 13:57:05 -08001451TEST_F(DumpstateUtilTest, RunCommandNoTitle) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001452 CreateFd("RunCommandWithNoArgs.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001453 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001454 EXPECT_THAT(out, StrEq("stdout\n"));
1455 EXPECT_THAT(err, StrEq("stderr\n"));
1456}
1457
Felipe Lemef0292972016-11-22 13:57:05 -08001458TEST_F(DumpstateUtilTest, RunCommandWithTitle) {
1459 CreateFd("RunCommandWithNoArgs.txt");
1460 EXPECT_EQ(0, RunCommand("I AM GROOT", {kSimpleCommand}));
1461 EXPECT_THAT(out, StrEq("------ I AM GROOT (" + kSimpleCommand + ") ------\nstdout\n"));
1462 EXPECT_THAT(err, StrEq("stderr\n"));
1463}
1464
Felipe Leme46b85da2016-11-21 17:40:45 -08001465TEST_F(DumpstateUtilTest, RunCommandWithOneArg) {
1466 CreateFd("RunCommandWithOneArg.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001467 EXPECT_EQ(0, RunCommand("", {kEchoCommand, "one"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001468 EXPECT_THAT(err, IsEmpty());
1469 EXPECT_THAT(out, StrEq("one\n"));
1470}
1471
1472TEST_F(DumpstateUtilTest, RunCommandWithMultipleArgs) {
1473 CreateFd("RunCommandWithMultipleArgs.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001474 EXPECT_EQ(0, RunCommand("", {kEchoCommand, "one", "is", "the", "loniest", "number"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001475 EXPECT_THAT(err, IsEmpty());
1476 EXPECT_THAT(out, StrEq("one is the loniest number\n"));
1477}
1478
1479TEST_F(DumpstateUtilTest, RunCommandWithLoggingMessage) {
1480 CreateFd("RunCommandWithLoggingMessage.txt");
1481 EXPECT_EQ(
Felipe Lemef0292972016-11-22 13:57:05 -08001482 0, RunCommand("", {kSimpleCommand},
Felipe Leme46b85da2016-11-21 17:40:45 -08001483 CommandOptions::WithTimeout(10).Log("COMMAND, Y U NO LOG FIRST?").Build()));
1484 EXPECT_THAT(out, StrEq("stdout\n"));
1485 EXPECT_THAT(err, StrEq("COMMAND, Y U NO LOG FIRST?stderr\n"));
1486}
1487
1488TEST_F(DumpstateUtilTest, RunCommandRedirectStderr) {
1489 CreateFd("RunCommandRedirectStderr.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001490 EXPECT_EQ(0, RunCommand("", {kSimpleCommand},
1491 CommandOptions::WithTimeout(10).RedirectStderr().Build()));
Felipe Leme46b85da2016-11-21 17:40:45 -08001492 EXPECT_THAT(out, IsEmpty());
1493 EXPECT_THAT(err, StrEq("stdout\nstderr\n"));
1494}
1495
1496TEST_F(DumpstateUtilTest, RunCommandDryRun) {
1497 CreateFd("RunCommandDryRun.txt");
1498 SetDryRun(true);
Felipe Lemef0292972016-11-22 13:57:05 -08001499 EXPECT_EQ(0, RunCommand("I AM GROOT", {kSimpleCommand}));
1500 EXPECT_THAT(out, StrEq(android::base::StringPrintf(
1501 "------ I AM GROOT (%s) ------\n\t(skipped on dry run)\n",
1502 kSimpleCommand.c_str())));
1503 EXPECT_THAT(err, IsEmpty());
1504}
1505
1506TEST_F(DumpstateUtilTest, RunCommandDryRunNoTitle) {
1507 CreateFd("RunCommandDryRun.txt");
1508 SetDryRun(true);
1509 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001510 EXPECT_THAT(
1511 out, StrEq(android::base::StringPrintf("%s: skipped on dry run\n", kSimpleCommand.c_str())));
1512 EXPECT_THAT(err, IsEmpty());
1513}
1514
1515TEST_F(DumpstateUtilTest, RunCommandDryRunAlways) {
1516 CreateFd("RunCommandDryRunAlways.txt");
1517 SetDryRun(true);
Felipe Lemef0292972016-11-22 13:57:05 -08001518 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(10).Always().Build()));
Felipe Leme46b85da2016-11-21 17:40:45 -08001519 EXPECT_THAT(out, StrEq("stdout\n"));
1520 EXPECT_THAT(err, StrEq("stderr\n"));
1521}
1522
1523TEST_F(DumpstateUtilTest, RunCommandNotFound) {
1524 CreateFd("RunCommandNotFound.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001525 EXPECT_NE(0, RunCommand("", {"/there/cannot/be/such/command"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001526 EXPECT_THAT(out, StartsWith("*** command '/there/cannot/be/such/command' failed: exit code"));
1527 EXPECT_THAT(err, StartsWith("execvp on command '/there/cannot/be/such/command' failed"));
1528}
1529
1530TEST_F(DumpstateUtilTest, RunCommandFails) {
1531 CreateFd("RunCommandFails.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001532 EXPECT_EQ(42, RunCommand("", {kSimpleCommand, "--exit", "42"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001533 EXPECT_THAT(out, StrEq("stdout\n*** command '" + kSimpleCommand +
1534 " --exit 42' failed: exit code 42\n"));
1535 EXPECT_THAT(err, StrEq("stderr\n*** command '" + kSimpleCommand +
1536 " --exit 42' failed: exit code 42\n"));
1537}
1538
1539TEST_F(DumpstateUtilTest, RunCommandCrashes) {
1540 CreateFd("RunCommandCrashes.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001541 EXPECT_NE(0, RunCommand("", {kSimpleCommand, "--crash"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001542 // We don't know the exit code, so check just the prefix.
1543 EXPECT_THAT(
1544 out, StartsWith("stdout\n*** command '" + kSimpleCommand + " --crash' failed: exit code"));
1545 EXPECT_THAT(
1546 err, StartsWith("stderr\n*** command '" + kSimpleCommand + " --crash' failed: exit code"));
1547}
1548
Vishnu Nair6921f802017-11-22 09:17:23 -08001549TEST_F(DumpstateUtilTest, RunCommandTimesoutWithSec) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001550 CreateFd("RunCommandTimesout.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001551 EXPECT_EQ(-1, RunCommand("", {kSimpleCommand, "--sleep", "2"},
1552 CommandOptions::WithTimeout(1).Build()));
Felipe Leme46b85da2016-11-21 17:40:45 -08001553 EXPECT_THAT(out, StartsWith("stdout line1\n*** command '" + kSimpleCommand +
1554 " --sleep 2' timed out after 1"));
1555 EXPECT_THAT(err, StartsWith("sleeping for 2s\n*** command '" + kSimpleCommand +
1556 " --sleep 2' timed out after 1"));
1557}
1558
Vishnu Nair6921f802017-11-22 09:17:23 -08001559TEST_F(DumpstateUtilTest, RunCommandTimesoutWithMsec) {
1560 CreateFd("RunCommandTimesout.txt");
1561 EXPECT_EQ(-1, RunCommand("", {kSimpleCommand, "--sleep", "2"},
1562 CommandOptions::WithTimeoutInMs(1000).Build()));
1563 EXPECT_THAT(out, StartsWith("stdout line1\n*** command '" + kSimpleCommand +
1564 " --sleep 2' timed out after 1"));
1565 EXPECT_THAT(err, StartsWith("sleeping for 2s\n*** command '" + kSimpleCommand +
1566 " --sleep 2' timed out after 1"));
1567}
1568
1569
Felipe Leme46b85da2016-11-21 17:40:45 -08001570TEST_F(DumpstateUtilTest, RunCommandIsKilled) {
1571 CreateFd("RunCommandIsKilled.txt");
1572 CaptureStderr();
1573
1574 std::thread t([=]() {
Felipe Lemef0292972016-11-22 13:57:05 -08001575 EXPECT_EQ(SIGTERM, RunCommandToFd(fd, "", {kSimpleCommand, "--pid", "--sleep", "20"},
Felipe Leme46b85da2016-11-21 17:40:45 -08001576 CommandOptions::WithTimeout(100).Always().Build()));
1577 });
1578
1579 // Capture pid and pre-sleep output.
1580 sleep(1); // Wait a little bit to make sure pid and 1st line were printed.
1581 std::string err = GetCapturedStderr();
1582 EXPECT_THAT(err, StrEq("sleeping for 20s\n"));
1583
1584 CaptureFdOut();
1585 std::vector<std::string> lines = android::base::Split(out, "\n");
1586 ASSERT_EQ(3, (int)lines.size()) << "Invalid lines before sleep: " << out;
1587
1588 int pid = atoi(lines[0].c_str());
1589 EXPECT_THAT(lines[1], StrEq("stdout line1"));
1590 EXPECT_THAT(lines[2], IsEmpty()); // \n
1591
1592 // Then kill the process.
1593 CaptureFdOut();
1594 CaptureStderr();
1595 ASSERT_EQ(0, kill(pid, SIGTERM)) << "failed to kill pid " << pid;
1596 t.join();
1597
1598 // Finally, check output after murder.
1599 CaptureFdOut();
1600 err = GetCapturedStderr();
1601
1602 // out starts with the pid, which is an unknown
1603 EXPECT_THAT(out, EndsWith("stdout line1\n*** command '" + kSimpleCommand +
1604 " --pid --sleep 20' failed: killed by signal 15\n"));
1605 EXPECT_THAT(err, StrEq("*** command '" + kSimpleCommand +
1606 " --pid --sleep 20' failed: killed by signal 15\n"));
1607}
1608
1609TEST_F(DumpstateUtilTest, RunCommandAsRootUserBuild) {
1610 if (!IsStandalone()) {
1611 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1612 // to Shell - need to refactor tests to avoid this problem)
1613 MYLOGE("Skipping DumpstateUtilTest.RunCommandAsRootUserBuild() on test suite\n")
1614 return;
1615 }
1616 CreateFd("RunCommandAsRootUserBuild.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001617 if (!PropertiesHelper::IsUserBuild()) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001618 // Emulates user build if necessarily.
1619 SetBuildType("user");
1620 }
1621
1622 DropRoot();
1623
Felipe Lemef0292972016-11-22 13:57:05 -08001624 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).AsRoot().Build()));
Felipe Leme46b85da2016-11-21 17:40:45 -08001625
1626 // We don't know the exact path of su, so we just check for the 'root ...' commands
1627 EXPECT_THAT(out, StartsWith("Skipping"));
1628 EXPECT_THAT(out, EndsWith("root " + kSimpleCommand + "' on user build.\n"));
1629 EXPECT_THAT(err, IsEmpty());
1630}
1631
1632TEST_F(DumpstateUtilTest, RunCommandAsRootNonUserBuild) {
1633 if (!IsStandalone()) {
1634 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1635 // to Shell - need to refactor tests to avoid this problem)
1636 MYLOGE("Skipping DumpstateUtilTest.RunCommandAsRootNonUserBuild() on test suite\n")
1637 return;
1638 }
1639 CreateFd("RunCommandAsRootNonUserBuild.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001640 if (PropertiesHelper::IsUserBuild()) {
Felipe Leme7447d7c2016-11-03 18:12:22 -07001641 ALOGI("Skipping RunCommandAsRootNonUserBuild on user builds\n");
1642 return;
1643 }
1644
1645 DropRoot();
1646
Felipe Lemef0292972016-11-22 13:57:05 -08001647 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
1648 CommandOptions::WithTimeout(1).AsRoot().Build()));
Felipe Leme7447d7c2016-11-03 18:12:22 -07001649
1650 EXPECT_THAT(out, StrEq("0\nstdout\n"));
1651 EXPECT_THAT(err, StrEq("stderr\n"));
1652}
Felipe Leme46b85da2016-11-21 17:40:45 -08001653
Yifan Hong48e83a12017-10-03 14:10:07 -07001654
1655TEST_F(DumpstateUtilTest, RunCommandAsRootIfAvailableOnUserBuild) {
1656 if (!IsStandalone()) {
1657 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1658 // to Shell - need to refactor tests to avoid this problem)
1659 MYLOGE("Skipping DumpstateUtilTest.RunCommandAsRootIfAvailableOnUserBuild() on test suite\n")
1660 return;
1661 }
1662 CreateFd("RunCommandAsRootIfAvailableOnUserBuild.txt");
1663 if (!PropertiesHelper::IsUserBuild()) {
1664 // Emulates user build if necessarily.
1665 SetBuildType("user");
1666 }
1667
1668 DropRoot();
1669
1670 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
1671 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
1672
1673 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
1674 EXPECT_THAT(err, StrEq("stderr\n"));
1675}
1676
1677TEST_F(DumpstateUtilTest, RunCommandAsRootIfAvailableOnDebugBuild) {
1678 if (!IsStandalone()) {
1679 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1680 // to Shell - need to refactor tests to avoid this problem)
1681 MYLOGE("Skipping DumpstateUtilTest.RunCommandAsRootIfAvailableOnDebugBuild() on test suite\n")
1682 return;
1683 }
1684 CreateFd("RunCommandAsRootIfAvailableOnDebugBuild.txt");
1685 if (PropertiesHelper::IsUserBuild()) {
1686 ALOGI("Skipping RunCommandAsRootNonUserBuild on user builds\n");
1687 return;
1688 }
1689
1690 DropRoot();
1691
1692 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
1693 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
1694
1695 EXPECT_THAT(out, StrEq("0\nstdout\n"));
1696 EXPECT_THAT(err, StrEq("stderr\n"));
1697}
1698
Felipe Leme46b85da2016-11-21 17:40:45 -08001699TEST_F(DumpstateUtilTest, RunCommandDropRoot) {
1700 if (!IsStandalone()) {
1701 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1702 // to Shell - need to refactor tests to avoid this problem)
1703 MYLOGE("Skipping DumpstateUtilTest.RunCommandDropRoot() on test suite\n")
1704 return;
1705 }
1706 CreateFd("RunCommandDropRoot.txt");
1707 // First check root case - only available when running with 'adb root'.
1708 uid_t uid = getuid();
1709 if (uid == 0) {
Felipe Lemef0292972016-11-22 13:57:05 -08001710 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001711 EXPECT_THAT(out, StrEq("0\nstdout\n"));
1712 EXPECT_THAT(err, StrEq("stderr\n"));
1713 return;
1714 }
1715 // Then run dropping root.
Felipe Lemef0292972016-11-22 13:57:05 -08001716 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
Felipe Leme46b85da2016-11-21 17:40:45 -08001717 CommandOptions::WithTimeout(1).DropRoot().Build()));
1718 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
1719 EXPECT_THAT(err, StrEq("drop_root_user(): already running as Shell\nstderr\n"));
1720}
1721
Felipe Lemef0292972016-11-22 13:57:05 -08001722TEST_F(DumpstateUtilTest, DumpFileNotFoundNoTitle) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001723 CreateFd("DumpFileNotFound.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001724 EXPECT_EQ(-1, DumpFile("", "/I/cant/believe/I/exist"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001725 EXPECT_THAT(out,
1726 StrEq("*** Error dumping /I/cant/believe/I/exist: No such file or directory\n"));
1727 EXPECT_THAT(err, IsEmpty());
1728}
1729
Felipe Lemef0292972016-11-22 13:57:05 -08001730TEST_F(DumpstateUtilTest, DumpFileNotFoundWithTitle) {
1731 CreateFd("DumpFileNotFound.txt");
1732 EXPECT_EQ(-1, DumpFile("Y U NO EXIST?", "/I/cant/believe/I/exist"));
1733 EXPECT_THAT(out, StrEq("*** Error dumping /I/cant/believe/I/exist (Y U NO EXIST?): No such "
1734 "file or directory\n"));
1735 EXPECT_THAT(err, IsEmpty());
1736}
1737
Felipe Leme46b85da2016-11-21 17:40:45 -08001738TEST_F(DumpstateUtilTest, DumpFileSingleLine) {
1739 CreateFd("DumpFileSingleLine.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001740 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001741 EXPECT_THAT(err, IsEmpty());
1742 EXPECT_THAT(out, StrEq("I AM LINE1\n")); // dumpstate adds missing newline
1743}
1744
1745TEST_F(DumpstateUtilTest, DumpFileSingleLineWithNewLine) {
1746 CreateFd("DumpFileSingleLineWithNewLine.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001747 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line-with-newline.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001748 EXPECT_THAT(err, IsEmpty());
1749 EXPECT_THAT(out, StrEq("I AM LINE1\n"));
1750}
1751
1752TEST_F(DumpstateUtilTest, DumpFileMultipleLines) {
1753 CreateFd("DumpFileMultipleLines.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001754 EXPECT_EQ(0, DumpFile("", kTestDataPath + "multiple-lines.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001755 EXPECT_THAT(err, IsEmpty());
1756 EXPECT_THAT(out, StrEq("I AM LINE1\nI AM LINE2\nI AM LINE3\n"));
1757}
1758
1759TEST_F(DumpstateUtilTest, DumpFileMultipleLinesWithNewLine) {
1760 CreateFd("DumpFileMultipleLinesWithNewLine.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001761 EXPECT_EQ(0, DumpFile("", kTestDataPath + "multiple-lines-with-newline.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001762 EXPECT_THAT(err, IsEmpty());
1763 EXPECT_THAT(out, StrEq("I AM LINE1\nI AM LINE2\nI AM LINE3\n"));
1764}
1765
Felipe Lemef0292972016-11-22 13:57:05 -08001766TEST_F(DumpstateUtilTest, DumpFileOnDryRunNoTitle) {
1767 CreateFd("DumpFileOnDryRun.txt");
1768 SetDryRun(true);
1769 std::string path = kTestDataPath + "single-line.txt";
1770 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
1771 EXPECT_THAT(err, IsEmpty());
1772 EXPECT_THAT(out, StrEq(path + ": skipped on dry run\n"));
1773}
1774
Felipe Leme46b85da2016-11-21 17:40:45 -08001775TEST_F(DumpstateUtilTest, DumpFileOnDryRun) {
1776 CreateFd("DumpFileOnDryRun.txt");
1777 SetDryRun(true);
1778 std::string path = kTestDataPath + "single-line.txt";
Felipe Lemef0292972016-11-22 13:57:05 -08001779 EXPECT_EQ(0, DumpFile("Might as well dump. Dump!", kTestDataPath + "single-line.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001780 EXPECT_THAT(err, IsEmpty());
Felipe Lemef0292972016-11-22 13:57:05 -08001781 EXPECT_THAT(
1782 out, StartsWith("------ Might as well dump. Dump! (" + kTestDataPath + "single-line.txt:"));
1783 EXPECT_THAT(out, EndsWith("skipped on dry run\n"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001784}
Ecco Park61ffcf72016-10-27 15:46:26 -07001785
1786TEST_F(DumpstateUtilTest, FindingPidWithExistingProcess) {
1787 // init process always has pid 1.
1788 EXPECT_EQ(1, FindPidOfProcess("init"));
1789 EXPECT_THAT(err, IsEmpty());
1790}
1791
1792TEST_F(DumpstateUtilTest, FindingPidWithNotExistingProcess) {
1793 // find the process with abnormal name.
1794 EXPECT_EQ(-1, FindPidOfProcess("abcdef12345-543"));
1795 EXPECT_THAT(err, StrEq("can't find the pid\n"));
1796}
Felipe Leme47e9be22016-12-21 15:37:07 -08001797
1798} // namespace dumpstate
1799} // namespace os
1800} // namespace android