blob: 4e6b084ff6e735eb396123b288450995f9f0aa1a [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());
Dan Shie177e8e2019-06-20 11:08:14 -0700108 const std::string kTestDataPath = kTestPath + "/tests/testdata/";
109 const std::string kSimpleCommand = kTestPath + "/dumpstate_test_fixture";
Felipe Leme7447d7c2016-11-03 18:12:22 -0700110 const std::string kEchoCommand = "/system/bin/echo";
111
112 /*
113 * Copies a text file fixture to a temporary file, returning it's path.
114 *
115 * Useful in cases where the test case changes the content of the tile.
116 */
117 std::string CopyTextFileFixture(const std::string& relative_name) {
118 std::string from = kTestDataPath + relative_name;
119 // Not using TemporaryFile because it's deleted at the end, and it's useful to keep it
120 // around for poking when the test fails.
121 std::string to = kTestDataPath + relative_name + ".tmp";
122 ALOGD("CopyTextFileFixture: from %s to %s\n", from.c_str(), to.c_str());
123 android::base::RemoveFileIfExists(to);
124 CopyTextFile(from, to);
125 return to.c_str();
126 }
127
Felipe Leme46b85da2016-11-21 17:40:45 -0800128 // Need functions that returns void to use assertions -
Felipe Leme7447d7c2016-11-03 18:12:22 -0700129 // https://github.com/google/googletest/blob/master/googletest/docs/AdvancedGuide.md#assertion-placement
Felipe Leme46b85da2016-11-21 17:40:45 -0800130 void ReadFileToString(const std::string& path, std::string* content) {
131 ASSERT_TRUE(android::base::ReadFileToString(path, content))
132 << "could not read contents from " << path;
133 }
134 void WriteStringToFile(const std::string& content, const std::string& path) {
135 ASSERT_TRUE(android::base::WriteStringToFile(content, path))
136 << "could not write contents to " << path;
137 }
138
139 private:
Felipe Leme7447d7c2016-11-03 18:12:22 -0700140 void CopyTextFile(const std::string& from, const std::string& to) {
141 std::string content;
Felipe Leme46b85da2016-11-21 17:40:45 -0800142 ReadFileToString(from, &content);
143 WriteStringToFile(content, to);
Felipe Leme7447d7c2016-11-03 18:12:22 -0700144 }
145};
146
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100147class DumpOptionsTest : public Test {
148 public:
149 virtual ~DumpOptionsTest() {
150 }
151 virtual void SetUp() {
152 options_ = Dumpstate::DumpOptions();
153 }
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000154 void TearDown() {
155 // Reset the property
156 property_set("dumpstate.options", "");
157 }
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100158 Dumpstate::DumpOptions options_;
159};
160
161TEST_F(DumpOptionsTest, InitializeNone) {
162 // clang-format off
163 char* argv[] = {
164 const_cast<char*>("dumpstate")
165 };
166 // clang-format on
167
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100168 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
169
170 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
Nandana Dutt58d72e22018-11-16 10:30:48 +0000171
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100172 EXPECT_FALSE(options_.do_add_date);
173 EXPECT_FALSE(options_.do_zip_file);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100174 EXPECT_FALSE(options_.use_socket);
175 EXPECT_FALSE(options_.use_control_socket);
176 EXPECT_FALSE(options_.show_header_only);
177 EXPECT_TRUE(options_.do_vibrate);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000178 EXPECT_FALSE(options_.do_fb);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100179 EXPECT_FALSE(options_.do_progress_updates);
180 EXPECT_FALSE(options_.is_remote_mode);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000181 EXPECT_FALSE(options_.do_broadcast);
182}
183
184TEST_F(DumpOptionsTest, InitializeAdbBugreport) {
185 // clang-format off
186 char* argv[] = {
187 const_cast<char*>("dumpstatez"),
188 const_cast<char*>("-S"),
189 const_cast<char*>("-d"),
190 const_cast<char*>("-z"),
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000191 };
192 // clang-format on
193
194 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
195
196 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
197 EXPECT_TRUE(options_.do_add_date);
198 EXPECT_TRUE(options_.do_zip_file);
199 EXPECT_TRUE(options_.use_control_socket);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000200
201 // Other options retain default values
202 EXPECT_TRUE(options_.do_vibrate);
203 EXPECT_FALSE(options_.show_header_only);
204 EXPECT_FALSE(options_.do_fb);
205 EXPECT_FALSE(options_.do_progress_updates);
206 EXPECT_FALSE(options_.is_remote_mode);
207 EXPECT_FALSE(options_.do_broadcast);
208 EXPECT_FALSE(options_.use_socket);
209}
210
211TEST_F(DumpOptionsTest, InitializeAdbShellBugreport) {
212 // clang-format off
213 char* argv[] = {
214 const_cast<char*>("dumpstate"),
215 const_cast<char*>("-s"),
216 };
217 // clang-format on
218
219 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
220
221 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
222 EXPECT_TRUE(options_.use_socket);
223
224 // Other options retain default values
225 EXPECT_TRUE(options_.do_vibrate);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000226 EXPECT_FALSE(options_.do_add_date);
227 EXPECT_FALSE(options_.do_zip_file);
228 EXPECT_FALSE(options_.use_control_socket);
229 EXPECT_FALSE(options_.show_header_only);
230 EXPECT_FALSE(options_.do_fb);
231 EXPECT_FALSE(options_.do_progress_updates);
232 EXPECT_FALSE(options_.is_remote_mode);
233 EXPECT_FALSE(options_.do_broadcast);
234}
235
236TEST_F(DumpOptionsTest, InitializeFullBugReport) {
237 // clang-format off
238 char* argv[] = {
239 const_cast<char*>("bugreport"),
240 const_cast<char*>("-d"),
241 const_cast<char*>("-p"),
242 const_cast<char*>("-B"),
243 const_cast<char*>("-z"),
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000244 };
245 // clang-format on
246 property_set("dumpstate.options", "bugreportfull");
247
248 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
249
250 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
251 EXPECT_TRUE(options_.do_add_date);
252 EXPECT_TRUE(options_.do_fb);
253 EXPECT_TRUE(options_.do_zip_file);
Nandana Dutt58d72e22018-11-16 10:30:48 +0000254 EXPECT_TRUE(options_.do_broadcast);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000255
256 // Other options retain default values
257 EXPECT_TRUE(options_.do_vibrate);
258 EXPECT_FALSE(options_.use_control_socket);
259 EXPECT_FALSE(options_.show_header_only);
260 EXPECT_FALSE(options_.do_progress_updates);
261 EXPECT_FALSE(options_.is_remote_mode);
262 EXPECT_FALSE(options_.use_socket);
263 EXPECT_FALSE(options_.do_start_service);
264}
265
266TEST_F(DumpOptionsTest, InitializeInteractiveBugReport) {
267 // clang-format off
268 char* argv[] = {
269 const_cast<char*>("bugreport"),
270 const_cast<char*>("-d"),
271 const_cast<char*>("-p"),
272 const_cast<char*>("-B"),
273 const_cast<char*>("-z"),
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000274 };
275 // clang-format on
276
277 property_set("dumpstate.options", "bugreportplus");
278
279 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
280
281 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
282 EXPECT_TRUE(options_.do_add_date);
283 EXPECT_TRUE(options_.do_broadcast);
284 EXPECT_TRUE(options_.do_zip_file);
285 EXPECT_TRUE(options_.do_progress_updates);
286 EXPECT_TRUE(options_.do_start_service);
287 EXPECT_FALSE(options_.do_fb);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000288
289 // Other options retain default values
290 EXPECT_TRUE(options_.do_vibrate);
291 EXPECT_FALSE(options_.use_control_socket);
292 EXPECT_FALSE(options_.show_header_only);
293 EXPECT_FALSE(options_.is_remote_mode);
294 EXPECT_FALSE(options_.use_socket);
295}
296
297TEST_F(DumpOptionsTest, InitializeRemoteBugReport) {
298 // clang-format off
299 char* argv[] = {
300 const_cast<char*>("bugreport"),
301 const_cast<char*>("-d"),
302 const_cast<char*>("-p"),
303 const_cast<char*>("-B"),
304 const_cast<char*>("-z"),
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000305 };
306 // clang-format on
307
308 property_set("dumpstate.options", "bugreportremote");
309
310 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
311
312 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
313 EXPECT_TRUE(options_.do_add_date);
314 EXPECT_TRUE(options_.do_broadcast);
315 EXPECT_TRUE(options_.do_zip_file);
316 EXPECT_TRUE(options_.is_remote_mode);
317 EXPECT_FALSE(options_.do_vibrate);
318 EXPECT_FALSE(options_.do_fb);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000319
320 // Other options retain default values
321 EXPECT_FALSE(options_.use_control_socket);
322 EXPECT_FALSE(options_.show_header_only);
323 EXPECT_FALSE(options_.do_progress_updates);
324 EXPECT_FALSE(options_.use_socket);
325}
326
327TEST_F(DumpOptionsTest, InitializeWearBugReport) {
328 // clang-format off
329 char* argv[] = {
330 const_cast<char*>("bugreport"),
331 const_cast<char*>("-d"),
332 const_cast<char*>("-p"),
333 const_cast<char*>("-B"),
334 const_cast<char*>("-z"),
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000335 };
336 // clang-format on
337
338 property_set("dumpstate.options", "bugreportwear");
339
340 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
341
342 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
343 EXPECT_TRUE(options_.do_add_date);
344 EXPECT_TRUE(options_.do_fb);
345 EXPECT_TRUE(options_.do_broadcast);
346 EXPECT_TRUE(options_.do_zip_file);
347 EXPECT_TRUE(options_.do_progress_updates);
348 EXPECT_TRUE(options_.do_start_service);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000349
350 // Other options retain default values
351 EXPECT_TRUE(options_.do_vibrate);
352 EXPECT_FALSE(options_.use_control_socket);
353 EXPECT_FALSE(options_.show_header_only);
354 EXPECT_FALSE(options_.is_remote_mode);
355 EXPECT_FALSE(options_.use_socket);
356}
357
358TEST_F(DumpOptionsTest, InitializeTelephonyBugReport) {
359 // clang-format off
360 char* argv[] = {
361 const_cast<char*>("bugreport"),
362 const_cast<char*>("-d"),
363 const_cast<char*>("-p"),
364 const_cast<char*>("-B"),
365 const_cast<char*>("-z"),
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000366 };
367 // clang-format on
368
369 property_set("dumpstate.options", "bugreporttelephony");
370
371 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
372
373 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
374 EXPECT_TRUE(options_.do_add_date);
Abhijeet Kaurd3cca0d2019-03-25 12:04:16 +0000375 EXPECT_FALSE(options_.do_fb);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000376 EXPECT_TRUE(options_.do_broadcast);
377 EXPECT_TRUE(options_.do_zip_file);
378 EXPECT_TRUE(options_.telephony_only);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000379
380 // Other options retain default values
381 EXPECT_TRUE(options_.do_vibrate);
382 EXPECT_FALSE(options_.use_control_socket);
383 EXPECT_FALSE(options_.show_header_only);
384 EXPECT_FALSE(options_.do_progress_updates);
385 EXPECT_FALSE(options_.is_remote_mode);
386 EXPECT_FALSE(options_.use_socket);
387}
388
389TEST_F(DumpOptionsTest, InitializeWifiBugReport) {
390 // clang-format off
391 char* argv[] = {
392 const_cast<char*>("bugreport"),
393 const_cast<char*>("-d"),
394 const_cast<char*>("-p"),
395 const_cast<char*>("-B"),
396 const_cast<char*>("-z"),
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000397 };
398 // clang-format on
399
400 property_set("dumpstate.options", "bugreportwifi");
401
402 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
403
404 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
405 EXPECT_TRUE(options_.do_add_date);
Abhijeet Kaurd3cca0d2019-03-25 12:04:16 +0000406 EXPECT_FALSE(options_.do_fb);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000407 EXPECT_TRUE(options_.do_broadcast);
408 EXPECT_TRUE(options_.do_zip_file);
409 EXPECT_TRUE(options_.wifi_only);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000410
411 // Other options retain default values
412 EXPECT_TRUE(options_.do_vibrate);
413 EXPECT_FALSE(options_.use_control_socket);
414 EXPECT_FALSE(options_.show_header_only);
415 EXPECT_FALSE(options_.do_progress_updates);
416 EXPECT_FALSE(options_.is_remote_mode);
417 EXPECT_FALSE(options_.use_socket);
418}
419
420TEST_F(DumpOptionsTest, InitializeDefaultBugReport) {
421 // default: commandline options are not overridden
422 // clang-format off
423 char* argv[] = {
424 const_cast<char*>("bugreport"),
425 const_cast<char*>("-d"),
426 const_cast<char*>("-p"),
427 const_cast<char*>("-B"),
428 const_cast<char*>("-z"),
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000429 };
430 // clang-format on
431
432 property_set("dumpstate.options", "");
433
434 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
435
436 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
437 EXPECT_TRUE(options_.do_add_date);
438 EXPECT_TRUE(options_.do_fb);
439 EXPECT_TRUE(options_.do_zip_file);
440 EXPECT_TRUE(options_.do_broadcast);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000441
442 // Other options retain default values
443 EXPECT_TRUE(options_.do_vibrate);
444 EXPECT_FALSE(options_.use_control_socket);
445 EXPECT_FALSE(options_.show_header_only);
446 EXPECT_FALSE(options_.do_progress_updates);
447 EXPECT_FALSE(options_.is_remote_mode);
448 EXPECT_FALSE(options_.use_socket);
449 EXPECT_FALSE(options_.wifi_only);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100450}
451
452TEST_F(DumpOptionsTest, InitializePartial1) {
453 // clang-format off
454 char* argv[] = {
455 const_cast<char*>("dumpstate"),
456 const_cast<char*>("-d"),
457 const_cast<char*>("-z"),
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100458 const_cast<char*>("-s"),
459 const_cast<char*>("-S"),
460
461 };
462 // clang-format on
463
464 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
465
466 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
467 EXPECT_TRUE(options_.do_add_date);
468 EXPECT_TRUE(options_.do_zip_file);
469 // TODO: Maybe we should trim the filename
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100470 EXPECT_TRUE(options_.use_socket);
471 EXPECT_TRUE(options_.use_control_socket);
472
473 // Other options retain default values
474 EXPECT_FALSE(options_.show_header_only);
475 EXPECT_TRUE(options_.do_vibrate);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000476 EXPECT_FALSE(options_.do_fb);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100477 EXPECT_FALSE(options_.do_progress_updates);
478 EXPECT_FALSE(options_.is_remote_mode);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000479 EXPECT_FALSE(options_.do_broadcast);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100480}
481
482TEST_F(DumpOptionsTest, InitializePartial2) {
483 // clang-format off
484 char* argv[] = {
485 const_cast<char*>("dumpstate"),
486 const_cast<char*>("-v"),
487 const_cast<char*>("-q"),
488 const_cast<char*>("-p"),
489 const_cast<char*>("-P"),
490 const_cast<char*>("-R"),
491 const_cast<char*>("-B"),
492 };
493 // clang-format on
494
495 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
496
497 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
498 EXPECT_TRUE(options_.show_header_only);
499 EXPECT_FALSE(options_.do_vibrate);
500 EXPECT_TRUE(options_.do_fb);
501 EXPECT_TRUE(options_.do_progress_updates);
502 EXPECT_TRUE(options_.is_remote_mode);
503 EXPECT_TRUE(options_.do_broadcast);
504
505 // Other options retain default values
506 EXPECT_FALSE(options_.do_add_date);
507 EXPECT_FALSE(options_.do_zip_file);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100508 EXPECT_FALSE(options_.use_socket);
509 EXPECT_FALSE(options_.use_control_socket);
510}
511
512TEST_F(DumpOptionsTest, InitializeHelp) {
513 // clang-format off
514 char* argv[] = {
515 const_cast<char*>("dumpstate"),
516 const_cast<char*>("-h")
517 };
518 // clang-format on
519
520 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
521
522 // -h is for help.
523 EXPECT_EQ(status, Dumpstate::RunStatus::HELP);
524}
525
526TEST_F(DumpOptionsTest, InitializeUnknown) {
527 // clang-format off
528 char* argv[] = {
529 const_cast<char*>("dumpstate"),
530 const_cast<char*>("-u") // unknown flag
531 };
532 // clang-format on
533
534 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
535
536 // -u is unknown.
537 EXPECT_EQ(status, Dumpstate::RunStatus::INVALID_INPUT);
538}
539
540TEST_F(DumpOptionsTest, ValidateOptionsNeedOutfile1) {
541 options_.do_zip_file = true;
Nandana Dutt9a76d202019-01-21 15:56:48 +0000542 // Writing to socket = !writing to file.
543 options_.use_socket = true;
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100544 EXPECT_FALSE(options_.ValidateOptions());
Nandana Dutt9a76d202019-01-21 15:56:48 +0000545
546 options_.use_socket = false;
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100547 EXPECT_TRUE(options_.ValidateOptions());
548}
549
550TEST_F(DumpOptionsTest, ValidateOptionsNeedOutfile2) {
551 options_.do_broadcast = true;
Nandana Dutt9a76d202019-01-21 15:56:48 +0000552 // Writing to socket = !writing to file.
553 options_.use_socket = true;
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100554 EXPECT_FALSE(options_.ValidateOptions());
Nandana Dutt9a76d202019-01-21 15:56:48 +0000555
556 options_.use_socket = false;
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100557 EXPECT_TRUE(options_.ValidateOptions());
558}
559
560TEST_F(DumpOptionsTest, ValidateOptionsNeedZipfile) {
561 options_.use_control_socket = true;
562 EXPECT_FALSE(options_.ValidateOptions());
563
564 options_.do_zip_file = true;
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100565 EXPECT_TRUE(options_.ValidateOptions());
566}
567
568TEST_F(DumpOptionsTest, ValidateOptionsUpdateProgressNeedsBroadcast) {
569 options_.do_progress_updates = true;
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100570 EXPECT_FALSE(options_.ValidateOptions());
571
572 options_.do_broadcast = true;
573 EXPECT_TRUE(options_.ValidateOptions());
574}
575
576TEST_F(DumpOptionsTest, ValidateOptionsRemoteMode) {
577 options_.is_remote_mode = true;
578 EXPECT_FALSE(options_.ValidateOptions());
579
580 options_.do_broadcast = true;
581 options_.do_zip_file = true;
582 options_.do_add_date = true;
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100583 EXPECT_TRUE(options_.ValidateOptions());
584}
585
Felipe Leme7447d7c2016-11-03 18:12:22 -0700586class DumpstateTest : public DumpstateBaseTest {
Felipe Leme4c2d6632016-09-28 14:32:00 -0700587 public:
588 void SetUp() {
Felipe Leme46b85da2016-11-21 17:40:45 -0800589 DumpstateBaseTest::SetUp();
Felipe Leme4c2d6632016-09-28 14:32:00 -0700590 SetDryRun(false);
Felipe Lemed80e6b62016-10-03 13:08:14 -0700591 SetBuildType(android::base::GetProperty("ro.build.type", "(unknown)"));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700592 ds.progress_.reset(new Progress());
Felipe Leme009ecbb2016-11-07 10:18:44 -0800593 ds.update_progress_threshold_ = 0;
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100594 ds.options_.reset(new Dumpstate::DumpOptions());
Felipe Leme4c2d6632016-09-28 14:32:00 -0700595 }
596
597 // Runs a command and capture `stdout` and `stderr`.
Felipe Leme9a523ae2016-10-20 15:10:33 -0700598 int RunCommand(const std::string& title, const std::vector<std::string>& full_command,
Felipe Leme4c2d6632016-09-28 14:32:00 -0700599 const CommandOptions& options = CommandOptions::DEFAULT) {
600 CaptureStdout();
601 CaptureStderr();
Felipe Leme9a523ae2016-10-20 15:10:33 -0700602 int status = ds.RunCommand(title, full_command, options);
Felipe Leme4c2d6632016-09-28 14:32:00 -0700603 out = GetCapturedStdout();
604 err = GetCapturedStderr();
605 return status;
606 }
607
Felipe Lemecef02982016-10-03 17:22:22 -0700608 // Dumps a file and capture `stdout` and `stderr`.
609 int DumpFile(const std::string& title, const std::string& path) {
610 CaptureStdout();
611 CaptureStderr();
612 int status = ds.DumpFile(title, path);
613 out = GetCapturedStdout();
614 err = GetCapturedStderr();
615 return status;
616 }
617
Felipe Leme009ecbb2016-11-07 10:18:44 -0800618 void SetProgress(long progress, long initial_max, long threshold = 0) {
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100619 ds.options_->do_progress_updates = true;
Felipe Leme009ecbb2016-11-07 10:18:44 -0800620 ds.update_progress_threshold_ = threshold;
621 ds.last_updated_progress_ = 0;
Felipe Leme7447d7c2016-11-03 18:12:22 -0700622 ds.progress_.reset(new Progress(initial_max, progress, 1.2));
623 }
624
Felipe Leme7447d7c2016-11-03 18:12:22 -0700625 std::string GetProgressMessage(const std::string& listener_name, int progress, int max,
Felipe Leme009ecbb2016-11-07 10:18:44 -0800626 int old_max = 0, bool update_progress = true) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700627 EXPECT_EQ(progress, ds.progress_->Get()) << "invalid progress";
628 EXPECT_EQ(max, ds.progress_->GetMax()) << "invalid max";
Felipe Leme75876a22016-10-27 16:31:27 -0700629
Felipe Leme7447d7c2016-11-03 18:12:22 -0700630 bool max_increased = old_max > 0;
Felipe Leme75876a22016-10-27 16:31:27 -0700631
Felipe Leme009ecbb2016-11-07 10:18:44 -0800632 std::string message = "";
Felipe Leme75876a22016-10-27 16:31:27 -0700633 if (max_increased) {
Felipe Leme009ecbb2016-11-07 10:18:44 -0800634 message =
Felipe Leme7447d7c2016-11-03 18:12:22 -0700635 android::base::StringPrintf("Adjusting max progress from %d to %d\n", old_max, max);
Felipe Leme75876a22016-10-27 16:31:27 -0700636 }
637
Felipe Leme009ecbb2016-11-07 10:18:44 -0800638 if (update_progress) {
Nandana Duttbabf6c72019-01-15 14:11:12 +0000639 message += android::base::StringPrintf("Setting progress (%s): %d/%d (%d%%)\n",
640 listener_name.c_str(), progress, max,
641 (100 * progress / max));
Felipe Leme009ecbb2016-11-07 10:18:44 -0800642 }
643
644 return message;
Felipe Lemed80e6b62016-10-03 13:08:14 -0700645 }
646
Felipe Leme4c2d6632016-09-28 14:32:00 -0700647 // `stdout` and `stderr` from the last command ran.
648 std::string out, err;
649
Felipe Lemefd8affa2016-09-30 17:38:57 -0700650 Dumpstate& ds = Dumpstate::GetInstance();
Felipe Leme4c2d6632016-09-28 14:32:00 -0700651};
652
653TEST_F(DumpstateTest, RunCommandNoArgs) {
654 EXPECT_EQ(-1, RunCommand("", {}));
655}
656
657TEST_F(DumpstateTest, RunCommandNoTitle) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700658 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700659 EXPECT_THAT(out, StrEq("stdout\n"));
660 EXPECT_THAT(err, StrEq("stderr\n"));
661}
662
663TEST_F(DumpstateTest, RunCommandWithTitle) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700664 EXPECT_EQ(0, RunCommand("I AM GROOT", {kSimpleCommand}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700665 EXPECT_THAT(err, StrEq("stderr\n"));
Greg Kaiser3a811c12019-05-21 12:48:59 -0700666 // The duration may not get output, depending on how long it takes,
667 // so we just check the prefix.
Felipe Lemefd8affa2016-09-30 17:38:57 -0700668 EXPECT_THAT(out,
Nandana Dutt47527b52019-03-29 15:34:36 +0000669 StartsWith("------ I AM GROOT (" + kSimpleCommand + ") ------\nstdout\n"));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700670}
671
Felipe Lemefd8affa2016-09-30 17:38:57 -0700672TEST_F(DumpstateTest, RunCommandWithLoggingMessage) {
Felipe Leme4c2d6632016-09-28 14:32:00 -0700673 EXPECT_EQ(
Felipe Leme7447d7c2016-11-03 18:12:22 -0700674 0, RunCommand("", {kSimpleCommand},
Felipe Lemefd8affa2016-09-30 17:38:57 -0700675 CommandOptions::WithTimeout(10).Log("COMMAND, Y U NO LOG FIRST?").Build()));
676 EXPECT_THAT(out, StrEq("stdout\n"));
677 EXPECT_THAT(err, StrEq("COMMAND, Y U NO LOG FIRST?stderr\n"));
678}
679
680TEST_F(DumpstateTest, RunCommandRedirectStderr) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700681 EXPECT_EQ(0, RunCommand("", {kSimpleCommand},
Felipe Lemefd8affa2016-09-30 17:38:57 -0700682 CommandOptions::WithTimeout(10).RedirectStderr().Build()));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700683 EXPECT_THAT(out, IsEmpty());
Felipe Lemefd8affa2016-09-30 17:38:57 -0700684 EXPECT_THAT(err, StrEq("stdout\nstderr\n"));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700685}
686
687TEST_F(DumpstateTest, RunCommandWithOneArg) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700688 EXPECT_EQ(0, RunCommand("", {kEchoCommand, "one"}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700689 EXPECT_THAT(err, IsEmpty());
690 EXPECT_THAT(out, StrEq("one\n"));
691}
692
Felipe Lemefd8affa2016-09-30 17:38:57 -0700693TEST_F(DumpstateTest, RunCommandWithMultipleArgs) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700694 EXPECT_EQ(0, RunCommand("", {kEchoCommand, "one", "is", "the", "loniest", "number"}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700695 EXPECT_THAT(err, IsEmpty());
696 EXPECT_THAT(out, StrEq("one is the loniest number\n"));
697}
698
699TEST_F(DumpstateTest, RunCommandDryRun) {
700 SetDryRun(true);
Felipe Leme7447d7c2016-11-03 18:12:22 -0700701 EXPECT_EQ(0, RunCommand("I AM GROOT", {kSimpleCommand}));
Greg Kaiser3a811c12019-05-21 12:48:59 -0700702 // The duration may not get output, depending on how long it takes,
703 // so we just check the prefix.
Felipe Leme7447d7c2016-11-03 18:12:22 -0700704 EXPECT_THAT(out, StartsWith("------ I AM GROOT (" + kSimpleCommand +
Nandana Dutt47527b52019-03-29 15:34:36 +0000705 ") ------\n\t(skipped on dry run)\n"));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700706 EXPECT_THAT(err, IsEmpty());
707}
708
709TEST_F(DumpstateTest, RunCommandDryRunNoTitle) {
710 SetDryRun(true);
Felipe Leme7447d7c2016-11-03 18:12:22 -0700711 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700712 EXPECT_THAT(out, IsEmpty());
713 EXPECT_THAT(err, IsEmpty());
714}
715
716TEST_F(DumpstateTest, RunCommandDryRunAlways) {
717 SetDryRun(true);
Felipe Leme7447d7c2016-11-03 18:12:22 -0700718 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(10).Always().Build()));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700719 EXPECT_THAT(out, StrEq("stdout\n"));
720 EXPECT_THAT(err, StrEq("stderr\n"));
721}
722
Felipe Lemefd8affa2016-09-30 17:38:57 -0700723TEST_F(DumpstateTest, RunCommandNotFound) {
724 EXPECT_NE(0, RunCommand("", {"/there/cannot/be/such/command"}));
725 EXPECT_THAT(out, StartsWith("*** command '/there/cannot/be/such/command' failed: exit code"));
726 EXPECT_THAT(err, StartsWith("execvp on command '/there/cannot/be/such/command' failed"));
727}
728
729TEST_F(DumpstateTest, RunCommandFails) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700730 EXPECT_EQ(42, RunCommand("", {kSimpleCommand, "--exit", "42"}));
731 EXPECT_THAT(out, StrEq("stdout\n*** command '" + kSimpleCommand +
Felipe Leme9a523ae2016-10-20 15:10:33 -0700732 " --exit 42' failed: exit code 42\n"));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700733 EXPECT_THAT(err, StrEq("stderr\n*** command '" + kSimpleCommand +
Felipe Leme9a523ae2016-10-20 15:10:33 -0700734 " --exit 42' failed: exit code 42\n"));
Felipe Lemefd8affa2016-09-30 17:38:57 -0700735}
736
737TEST_F(DumpstateTest, RunCommandCrashes) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700738 EXPECT_NE(0, RunCommand("", {kSimpleCommand, "--crash"}));
Felipe Lemefd8affa2016-09-30 17:38:57 -0700739 // We don't know the exit code, so check just the prefix.
740 EXPECT_THAT(
Felipe Leme7447d7c2016-11-03 18:12:22 -0700741 out, StartsWith("stdout\n*** command '" + kSimpleCommand + " --crash' failed: exit code"));
Felipe Lemefd8affa2016-09-30 17:38:57 -0700742 EXPECT_THAT(
Felipe Leme7447d7c2016-11-03 18:12:22 -0700743 err, StartsWith("stderr\n*** command '" + kSimpleCommand + " --crash' failed: exit code"));
Felipe Lemefd8affa2016-09-30 17:38:57 -0700744}
745
746TEST_F(DumpstateTest, RunCommandTimesout) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700747 EXPECT_EQ(-1, RunCommand("", {kSimpleCommand, "--sleep", "2"},
Felipe Lemefd8affa2016-09-30 17:38:57 -0700748 CommandOptions::WithTimeout(1).Build()));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700749 EXPECT_THAT(out, StartsWith("stdout line1\n*** command '" + kSimpleCommand +
Felipe Lemefd8affa2016-09-30 17:38:57 -0700750 " --sleep 2' timed out after 1"));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700751 EXPECT_THAT(err, StartsWith("sleeping for 2s\n*** command '" + kSimpleCommand +
Felipe Lemefd8affa2016-09-30 17:38:57 -0700752 " --sleep 2' timed out after 1"));
753}
754
755TEST_F(DumpstateTest, RunCommandIsKilled) {
756 CaptureStdout();
757 CaptureStderr();
758
759 std::thread t([=]() {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700760 EXPECT_EQ(SIGTERM, ds.RunCommand("", {kSimpleCommand, "--pid", "--sleep", "20"},
Felipe Lemefd8affa2016-09-30 17:38:57 -0700761 CommandOptions::WithTimeout(100).Always().Build()));
762 });
763
764 // Capture pid and pre-sleep output.
765 sleep(1); // Wait a little bit to make sure pid and 1st line were printed.
766 std::string err = GetCapturedStderr();
767 EXPECT_THAT(err, StrEq("sleeping for 20s\n"));
768
769 std::string out = GetCapturedStdout();
770 std::vector<std::string> lines = android::base::Split(out, "\n");
771 ASSERT_EQ(3, (int)lines.size()) << "Invalid lines before sleep: " << out;
772
773 int pid = atoi(lines[0].c_str());
774 EXPECT_THAT(lines[1], StrEq("stdout line1"));
775 EXPECT_THAT(lines[2], IsEmpty()); // \n
776
777 // Then kill the process.
778 CaptureStdout();
779 CaptureStderr();
780 ASSERT_EQ(0, kill(pid, SIGTERM)) << "failed to kill pid " << pid;
781 t.join();
782
783 // Finally, check output after murder.
784 out = GetCapturedStdout();
785 err = GetCapturedStderr();
786
Felipe Leme7447d7c2016-11-03 18:12:22 -0700787 EXPECT_THAT(out, StrEq("*** command '" + kSimpleCommand +
Felipe Lemefd8affa2016-09-30 17:38:57 -0700788 " --pid --sleep 20' failed: killed by signal 15\n"));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700789 EXPECT_THAT(err, StrEq("*** command '" + kSimpleCommand +
Felipe Lemefd8affa2016-09-30 17:38:57 -0700790 " --pid --sleep 20' failed: killed by signal 15\n"));
791}
792
Felipe Leme75876a22016-10-27 16:31:27 -0700793TEST_F(DumpstateTest, RunCommandProgress) {
794 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
795 ds.listener_ = listener;
796 ds.listener_name_ = "FoxMulder";
Felipe Leme7447d7c2016-11-03 18:12:22 -0700797 SetProgress(0, 30);
Felipe Leme75876a22016-10-27 16:31:27 -0700798
799 EXPECT_CALL(*listener, onProgressUpdated(20));
Nandana Duttbabf6c72019-01-15 14:11:12 +0000800 EXPECT_CALL(*listener, onProgress(66)); // 20/30 %
Felipe Leme7447d7c2016-11-03 18:12:22 -0700801 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(20).Build()));
Felipe Leme75876a22016-10-27 16:31:27 -0700802 std::string progress_message = GetProgressMessage(ds.listener_name_, 20, 30);
803 EXPECT_THAT(out, StrEq("stdout\n"));
804 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
805
806 EXPECT_CALL(*listener, onProgressUpdated(30));
Nandana Duttbabf6c72019-01-15 14:11:12 +0000807 EXPECT_CALL(*listener, onProgress(100)); // 35/35 %
Felipe Leme7447d7c2016-11-03 18:12:22 -0700808 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(10).Build()));
Felipe Leme75876a22016-10-27 16:31:27 -0700809 progress_message = GetProgressMessage(ds.listener_name_, 30, 30);
810 EXPECT_THAT(out, StrEq("stdout\n"));
811 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
812
813 // Run a command that will increase maximum timeout.
814 EXPECT_CALL(*listener, onProgressUpdated(31));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700815 EXPECT_CALL(*listener, onMaxProgressUpdated(37));
Nandana Duttbabf6c72019-01-15 14:11:12 +0000816 EXPECT_CALL(*listener, onProgress(83)); // 31/37 %
Felipe Leme7447d7c2016-11-03 18:12:22 -0700817 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).Build()));
818 progress_message = GetProgressMessage(ds.listener_name_, 31, 37, 30); // 20% increase
Felipe Leme75876a22016-10-27 16:31:27 -0700819 EXPECT_THAT(out, StrEq("stdout\n"));
820 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
821
822 // Make sure command ran while in dry_run is counted.
823 SetDryRun(true);
824 EXPECT_CALL(*listener, onProgressUpdated(35));
Nandana Duttbabf6c72019-01-15 14:11:12 +0000825 EXPECT_CALL(*listener, onProgress(94)); // 35/37 %
Felipe Leme7447d7c2016-11-03 18:12:22 -0700826 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(4).Build()));
827 progress_message = GetProgressMessage(ds.listener_name_, 35, 37);
Felipe Leme75876a22016-10-27 16:31:27 -0700828 EXPECT_THAT(out, IsEmpty());
829 EXPECT_THAT(err, StrEq(progress_message));
830
831 ds.listener_.clear();
832}
833
Felipe Leme009ecbb2016-11-07 10:18:44 -0800834TEST_F(DumpstateTest, RunCommandProgressIgnoreThreshold) {
835 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
836 ds.listener_ = listener;
837 ds.listener_name_ = "FoxMulder";
838 SetProgress(0, 8, 5); // 8 max, 5 threshold
839
840 // First update should always be sent.
841 EXPECT_CALL(*listener, onProgressUpdated(1));
Nandana Duttbabf6c72019-01-15 14:11:12 +0000842 EXPECT_CALL(*listener, onProgress(12)); // 1/12 %
Felipe Leme009ecbb2016-11-07 10:18:44 -0800843 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).Build()));
844 std::string progress_message = GetProgressMessage(ds.listener_name_, 1, 8);
845 EXPECT_THAT(out, StrEq("stdout\n"));
846 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
847
848 // Fourth update should be ignored because it's between the threshold (5 -1 = 4 < 5).
849 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(4).Build()));
850 EXPECT_THAT(out, StrEq("stdout\n"));
851 EXPECT_THAT(err, StrEq("stderr\n"));
852
853 // Third update should be sent because it reaches threshold (6 - 1 = 5).
854 EXPECT_CALL(*listener, onProgressUpdated(6));
Nandana Duttbabf6c72019-01-15 14:11:12 +0000855 EXPECT_CALL(*listener, onProgress(75)); // 6/8 %
Felipe Leme009ecbb2016-11-07 10:18:44 -0800856 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).Build()));
857 progress_message = GetProgressMessage(ds.listener_name_, 6, 8);
858 EXPECT_THAT(out, StrEq("stdout\n"));
859 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
860
861 // Fourth update should be ignored because it's between the threshold (9 - 6 = 3 < 5).
862 // But max update should be sent.
863 EXPECT_CALL(*listener, onMaxProgressUpdated(10)); // 9 * 120% = 10.8 = 10
864 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(3).Build()));
865 progress_message = GetProgressMessage(ds.listener_name_, 9, 10, 8, false);
866 EXPECT_THAT(out, StrEq("stdout\n"));
867 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
868
869 ds.listener_.clear();
870}
871
Felipe Lemed80e6b62016-10-03 13:08:14 -0700872TEST_F(DumpstateTest, RunCommandDropRoot) {
Felipe Leme46b85da2016-11-21 17:40:45 -0800873 if (!IsStandalone()) {
874 // TODO: temporarily disabled because it might cause other tests to fail after dropping
875 // to Shell - need to refactor tests to avoid this problem)
876 MYLOGE("Skipping DumpstateTest.RunCommandDropRoot() on test suite\n")
877 return;
878 }
Felipe Lemed80e6b62016-10-03 13:08:14 -0700879 // First check root case - only available when running with 'adb root'.
880 uid_t uid = getuid();
881 if (uid == 0) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700882 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"}));
Felipe Lemed80e6b62016-10-03 13:08:14 -0700883 EXPECT_THAT(out, StrEq("0\nstdout\n"));
884 EXPECT_THAT(err, StrEq("stderr\n"));
885 return;
886 }
Felipe Leme7447d7c2016-11-03 18:12:22 -0700887 // Then run dropping root.
888 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
Felipe Lemed80e6b62016-10-03 13:08:14 -0700889 CommandOptions::WithTimeout(1).DropRoot().Build()));
890 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
Felipe Leme26c41572016-10-06 14:34:43 -0700891 EXPECT_THAT(err, StrEq("drop_root_user(): already running as Shell\nstderr\n"));
Felipe Lemed80e6b62016-10-03 13:08:14 -0700892}
893
894TEST_F(DumpstateTest, RunCommandAsRootUserBuild) {
Felipe Leme46b85da2016-11-21 17:40:45 -0800895 if (!IsStandalone()) {
896 // TODO: temporarily disabled because it might cause other tests to fail after dropping
897 // to Shell - need to refactor tests to avoid this problem)
898 MYLOGE("Skipping DumpstateTest.RunCommandAsRootUserBuild() on test suite\n")
899 return;
900 }
Felipe Lemef0292972016-11-22 13:57:05 -0800901 if (!PropertiesHelper::IsUserBuild()) {
Felipe Lemed80e6b62016-10-03 13:08:14 -0700902 // Emulates user build if necessarily.
903 SetBuildType("user");
904 }
905
906 DropRoot();
907
Felipe Leme7447d7c2016-11-03 18:12:22 -0700908 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).AsRoot().Build()));
Felipe Lemed80e6b62016-10-03 13:08:14 -0700909
910 // We don't know the exact path of su, so we just check for the 'root ...' commands
911 EXPECT_THAT(out, StartsWith("Skipping"));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700912 EXPECT_THAT(out, EndsWith("root " + kSimpleCommand + "' on user build.\n"));
Felipe Lemed80e6b62016-10-03 13:08:14 -0700913 EXPECT_THAT(err, IsEmpty());
914}
915
Felipe Leme46b85da2016-11-21 17:40:45 -0800916TEST_F(DumpstateTest, RunCommandAsRootNonUserBuild) {
917 if (!IsStandalone()) {
918 // TODO: temporarily disabled because it might cause other tests to fail after dropping
919 // to Shell - need to refactor tests to avoid this problem)
920 MYLOGE("Skipping DumpstateTest.RunCommandAsRootNonUserBuild() on test suite\n")
921 return;
922 }
Felipe Lemef0292972016-11-22 13:57:05 -0800923 if (PropertiesHelper::IsUserBuild()) {
Felipe Leme46b85da2016-11-21 17:40:45 -0800924 ALOGI("Skipping RunCommandAsRootNonUserBuild on user builds\n");
925 return;
926 }
927
928 DropRoot();
929
930 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
931 CommandOptions::WithTimeout(1).AsRoot().Build()));
932
933 EXPECT_THAT(out, StrEq("0\nstdout\n"));
934 EXPECT_THAT(err, StrEq("stderr\n"));
935}
936
Nandana Dutt4b392be2018-11-02 16:17:05 +0000937TEST_F(DumpstateTest, RunCommandAsRootNonUserBuild_withUnroot) {
938 if (!IsStandalone()) {
939 // TODO: temporarily disabled because it might cause other tests to fail after dropping
940 // to Shell - need to refactor tests to avoid this problem)
941 MYLOGE(
942 "Skipping DumpstateTest.RunCommandAsRootNonUserBuild_withUnroot() "
943 "on test suite\n")
944 return;
945 }
946 if (PropertiesHelper::IsUserBuild()) {
947 ALOGI("Skipping RunCommandAsRootNonUserBuild_withUnroot on user builds\n");
948 return;
949 }
950
951 // Same test as above, but with unroot property set, which will override su availability.
952 SetUnroot(true);
953 DropRoot();
954
955 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
956 CommandOptions::WithTimeout(1).AsRoot().Build()));
957
958 // AsRoot is ineffective.
959 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
960 EXPECT_THAT(err, StrEq("drop_root_user(): already running as Shell\nstderr\n"));
961}
962
Yifan Hong48e83a12017-10-03 14:10:07 -0700963TEST_F(DumpstateTest, RunCommandAsRootIfAvailableOnUserBuild) {
964 if (!IsStandalone()) {
965 // TODO: temporarily disabled because it might cause other tests to fail after dropping
966 // to Shell - need to refactor tests to avoid this problem)
967 MYLOGE("Skipping DumpstateTest.RunCommandAsRootIfAvailableOnUserBuild() on test suite\n")
968 return;
969 }
970 if (!PropertiesHelper::IsUserBuild()) {
971 // Emulates user build if necessarily.
972 SetBuildType("user");
973 }
974
975 DropRoot();
976
977 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
978 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
979
980 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
981 EXPECT_THAT(err, StrEq("stderr\n"));
982}
983
984TEST_F(DumpstateTest, RunCommandAsRootIfAvailableOnDebugBuild) {
985 if (!IsStandalone()) {
986 // TODO: temporarily disabled because it might cause other tests to fail after dropping
987 // to Shell - need to refactor tests to avoid this problem)
988 MYLOGE("Skipping DumpstateTest.RunCommandAsRootIfAvailableOnDebugBuild() on test suite\n")
989 return;
990 }
991 if (PropertiesHelper::IsUserBuild()) {
992 ALOGI("Skipping RunCommandAsRootNonUserBuild on user builds\n");
993 return;
994 }
995
996 DropRoot();
997
998 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
999 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
1000
1001 EXPECT_THAT(out, StrEq("0\nstdout\n"));
1002 EXPECT_THAT(err, StrEq("stderr\n"));
1003}
1004
Nandana Dutt4b392be2018-11-02 16:17:05 +00001005TEST_F(DumpstateTest, RunCommandAsRootIfAvailableOnDebugBuild_withUnroot) {
1006 if (!IsStandalone()) {
1007 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1008 // to Shell - need to refactor tests to avoid this problem)
1009 MYLOGE(
1010 "Skipping DumpstateTest.RunCommandAsRootIfAvailableOnDebugBuild_withUnroot() "
1011 "on test suite\n")
1012 return;
1013 }
1014 if (PropertiesHelper::IsUserBuild()) {
1015 ALOGI("Skipping RunCommandAsRootIfAvailableOnDebugBuild_withUnroot on user builds\n");
1016 return;
1017 }
1018 // Same test as above, but with unroot property set, which will override su availability.
1019 SetUnroot(true);
1020
1021 DropRoot();
1022
1023 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
1024 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
1025
1026 // It's a userdebug build, so "su root" should be available, but unroot=true overrides it.
1027 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
1028 EXPECT_THAT(err, StrEq("stderr\n"));
1029}
1030
Felipe Lemecef02982016-10-03 17:22:22 -07001031TEST_F(DumpstateTest, DumpFileNotFoundNoTitle) {
1032 EXPECT_EQ(-1, DumpFile("", "/I/cant/believe/I/exist"));
1033 EXPECT_THAT(out,
1034 StrEq("*** Error dumping /I/cant/believe/I/exist: No such file or directory\n"));
1035 EXPECT_THAT(err, IsEmpty());
1036}
1037
1038TEST_F(DumpstateTest, DumpFileNotFoundWithTitle) {
1039 EXPECT_EQ(-1, DumpFile("Y U NO EXIST?", "/I/cant/believe/I/exist"));
1040 EXPECT_THAT(err, IsEmpty());
Greg Kaiser3a811c12019-05-21 12:48:59 -07001041 // The duration may not get output, depending on how long it takes,
1042 // so we just check the prefix.
Felipe Lemecef02982016-10-03 17:22:22 -07001043 EXPECT_THAT(out, StartsWith("*** Error dumping /I/cant/believe/I/exist (Y U NO EXIST?): No "
1044 "such file or directory\n"));
Felipe Lemecef02982016-10-03 17:22:22 -07001045}
1046
1047TEST_F(DumpstateTest, DumpFileSingleLine) {
Felipe Leme7447d7c2016-11-03 18:12:22 -07001048 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -07001049 EXPECT_THAT(err, IsEmpty());
1050 EXPECT_THAT(out, StrEq("I AM LINE1\n")); // dumpstate adds missing newline
1051}
1052
1053TEST_F(DumpstateTest, DumpFileSingleLineWithNewLine) {
Felipe Leme7447d7c2016-11-03 18:12:22 -07001054 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line-with-newline.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -07001055 EXPECT_THAT(err, IsEmpty());
1056 EXPECT_THAT(out, StrEq("I AM LINE1\n"));
1057}
1058
1059TEST_F(DumpstateTest, DumpFileMultipleLines) {
Felipe Leme7447d7c2016-11-03 18:12:22 -07001060 EXPECT_EQ(0, DumpFile("", kTestDataPath + "multiple-lines.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -07001061 EXPECT_THAT(err, IsEmpty());
1062 EXPECT_THAT(out, StrEq("I AM LINE1\nI AM LINE2\nI AM LINE3\n"));
1063}
1064
1065TEST_F(DumpstateTest, DumpFileMultipleLinesWithNewLine) {
Felipe Leme7447d7c2016-11-03 18:12:22 -07001066 EXPECT_EQ(0, DumpFile("", kTestDataPath + "multiple-lines-with-newline.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -07001067 EXPECT_THAT(err, IsEmpty());
1068 EXPECT_THAT(out, StrEq("I AM LINE1\nI AM LINE2\nI AM LINE3\n"));
1069}
1070
1071TEST_F(DumpstateTest, DumpFileOnDryRunNoTitle) {
1072 SetDryRun(true);
Felipe Leme7447d7c2016-11-03 18:12:22 -07001073 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -07001074 EXPECT_THAT(err, IsEmpty());
1075 EXPECT_THAT(out, IsEmpty());
1076}
1077
1078TEST_F(DumpstateTest, DumpFileOnDryRun) {
1079 SetDryRun(true);
Felipe Leme7447d7c2016-11-03 18:12:22 -07001080 EXPECT_EQ(0, DumpFile("Might as well dump. Dump!", kTestDataPath + "single-line.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -07001081 EXPECT_THAT(err, IsEmpty());
Felipe Leme46b85da2016-11-21 17:40:45 -08001082 EXPECT_THAT(
1083 out, StartsWith("------ Might as well dump. Dump! (" + kTestDataPath + "single-line.txt:"));
Nandana Dutt47527b52019-03-29 15:34:36 +00001084 EXPECT_THAT(out, HasSubstr("\n\t(skipped on dry run)\n"));
Felipe Lemecef02982016-10-03 17:22:22 -07001085}
1086
Felipe Leme75876a22016-10-27 16:31:27 -07001087TEST_F(DumpstateTest, DumpFileUpdateProgress) {
1088 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
1089 ds.listener_ = listener;
1090 ds.listener_name_ = "FoxMulder";
Felipe Leme7447d7c2016-11-03 18:12:22 -07001091 SetProgress(0, 30);
Felipe Leme75876a22016-10-27 16:31:27 -07001092
1093 EXPECT_CALL(*listener, onProgressUpdated(5));
Nandana Duttbabf6c72019-01-15 14:11:12 +00001094 EXPECT_CALL(*listener, onProgress(16)); // 5/30 %
Felipe Leme7447d7c2016-11-03 18:12:22 -07001095 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
Felipe Leme75876a22016-10-27 16:31:27 -07001096
1097 std::string progress_message =
1098 GetProgressMessage(ds.listener_name_, 5, 30); // TODO: unhardcode WEIGHT_FILE (5)?
1099 EXPECT_THAT(err, StrEq(progress_message));
1100 EXPECT_THAT(out, StrEq("I AM LINE1\n")); // dumpstate adds missing newline
1101
1102 ds.listener_.clear();
1103}
1104
Felipe Leme7447d7c2016-11-03 18:12:22 -07001105class DumpstateServiceTest : public DumpstateBaseTest {
Felipe Leme75876a22016-10-27 16:31:27 -07001106 public:
1107 DumpstateService dss;
1108};
1109
1110TEST_F(DumpstateServiceTest, SetListenerNoName) {
1111 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
Felipe Leme009ecbb2016-11-07 10:18:44 -08001112 sp<IDumpstateToken> token;
Vishnu Nair20cf5032018-01-05 13:15:49 -08001113 EXPECT_TRUE(dss.setListener("", listener, /* getSectionDetails = */ false, &token).isOk());
Felipe Leme009ecbb2016-11-07 10:18:44 -08001114 ASSERT_THAT(token, IsNull());
Felipe Leme75876a22016-10-27 16:31:27 -07001115}
1116
1117TEST_F(DumpstateServiceTest, SetListenerNoPointer) {
Felipe Leme009ecbb2016-11-07 10:18:44 -08001118 sp<IDumpstateToken> token;
Vishnu Nair20cf5032018-01-05 13:15:49 -08001119 EXPECT_TRUE(
1120 dss.setListener("whatever", nullptr, /* getSectionDetails = */ false, &token).isOk());
Felipe Leme009ecbb2016-11-07 10:18:44 -08001121 ASSERT_THAT(token, IsNull());
Felipe Leme75876a22016-10-27 16:31:27 -07001122}
1123
1124TEST_F(DumpstateServiceTest, SetListenerTwice) {
1125 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
Felipe Leme009ecbb2016-11-07 10:18:44 -08001126 sp<IDumpstateToken> token;
Vishnu Nair20cf5032018-01-05 13:15:49 -08001127 EXPECT_TRUE(
1128 dss.setListener("whatever", listener, /* getSectionDetails = */ false, &token).isOk());
Felipe Leme009ecbb2016-11-07 10:18:44 -08001129 ASSERT_THAT(token, NotNull());
Felipe Leme75876a22016-10-27 16:31:27 -07001130 EXPECT_THAT(Dumpstate::GetInstance().listener_name_, StrEq("whatever"));
Vishnu Nair20cf5032018-01-05 13:15:49 -08001131 EXPECT_FALSE(Dumpstate::GetInstance().report_section_);
Felipe Leme75876a22016-10-27 16:31:27 -07001132
Felipe Leme009ecbb2016-11-07 10:18:44 -08001133 token.clear();
Vishnu Nair20cf5032018-01-05 13:15:49 -08001134 EXPECT_TRUE(
1135 dss.setListener("whatsoever", listener, /* getSectionDetails = */ false, &token).isOk());
Felipe Leme009ecbb2016-11-07 10:18:44 -08001136 ASSERT_THAT(token, IsNull());
1137 EXPECT_THAT(Dumpstate::GetInstance().listener_name_, StrEq("whatever"));
Vishnu Nair20cf5032018-01-05 13:15:49 -08001138 EXPECT_FALSE(Dumpstate::GetInstance().report_section_);
1139}
1140
1141TEST_F(DumpstateServiceTest, SetListenerWithSectionDetails) {
1142 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
1143 sp<IDumpstateToken> token;
1144 Dumpstate::GetInstance().listener_ = nullptr;
1145 EXPECT_TRUE(
1146 dss.setListener("whatever", listener, /* getSectionDetails = */ true, &token).isOk());
1147 ASSERT_THAT(token, NotNull());
1148 EXPECT_THAT(Dumpstate::GetInstance().listener_name_, StrEq("whatever"));
1149 EXPECT_TRUE(Dumpstate::GetInstance().report_section_);
Felipe Leme75876a22016-10-27 16:31:27 -07001150}
Felipe Leme7447d7c2016-11-03 18:12:22 -07001151
1152class ProgressTest : public DumpstateBaseTest {
1153 public:
1154 Progress GetInstance(int32_t max, double growth_factor, const std::string& path = "") {
1155 return Progress(max, growth_factor, path);
1156 }
1157
1158 void AssertStats(const std::string& path, int32_t expected_runs, int32_t expected_average) {
1159 std::string expected_content =
1160 android::base::StringPrintf("%d %d\n", expected_runs, expected_average);
1161 std::string actual_content;
Felipe Leme46b85da2016-11-21 17:40:45 -08001162 ReadFileToString(path, &actual_content);
Felipe Leme7447d7c2016-11-03 18:12:22 -07001163 ASSERT_THAT(actual_content, StrEq(expected_content)) << "invalid stats on " << path;
1164 }
1165};
1166
1167TEST_F(ProgressTest, SimpleTest) {
1168 Progress progress;
1169 EXPECT_EQ(0, progress.Get());
1170 EXPECT_EQ(Progress::kDefaultMax, progress.GetInitialMax());
1171 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1172
1173 bool max_increased = progress.Inc(1);
1174 EXPECT_EQ(1, progress.Get());
1175 EXPECT_EQ(Progress::kDefaultMax, progress.GetInitialMax());
1176 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1177 EXPECT_FALSE(max_increased);
1178
1179 // Ignore negative increase.
1180 max_increased = progress.Inc(-1);
1181 EXPECT_EQ(1, progress.Get());
1182 EXPECT_EQ(Progress::kDefaultMax, progress.GetInitialMax());
1183 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1184 EXPECT_FALSE(max_increased);
1185}
1186
1187TEST_F(ProgressTest, MaxGrowsInsideNewRange) {
1188 Progress progress = GetInstance(10, 1.2); // 20% growth factor
1189 EXPECT_EQ(0, progress.Get());
1190 EXPECT_EQ(10, progress.GetInitialMax());
1191 EXPECT_EQ(10, progress.GetMax());
1192
1193 // No increase
1194 bool max_increased = progress.Inc(10);
1195 EXPECT_EQ(10, progress.Get());
1196 EXPECT_EQ(10, progress.GetMax());
1197 EXPECT_FALSE(max_increased);
1198
1199 // Increase, with new value < max*20%
1200 max_increased = progress.Inc(1);
1201 EXPECT_EQ(11, progress.Get());
1202 EXPECT_EQ(13, progress.GetMax()); // 11 average * 20% growth = 13.2 = 13
1203 EXPECT_TRUE(max_increased);
1204}
1205
1206TEST_F(ProgressTest, MaxGrowsOutsideNewRange) {
1207 Progress progress = GetInstance(10, 1.2); // 20% growth factor
1208 EXPECT_EQ(0, progress.Get());
1209 EXPECT_EQ(10, progress.GetInitialMax());
1210 EXPECT_EQ(10, progress.GetMax());
1211
1212 // No increase
1213 bool max_increased = progress.Inc(10);
1214 EXPECT_EQ(10, progress.Get());
1215 EXPECT_EQ(10, progress.GetMax());
1216 EXPECT_FALSE(max_increased);
1217
1218 // Increase, with new value > max*20%
1219 max_increased = progress.Inc(5);
1220 EXPECT_EQ(15, progress.Get());
1221 EXPECT_EQ(18, progress.GetMax()); // 15 average * 20% growth = 18
1222 EXPECT_TRUE(max_increased);
1223}
1224
1225TEST_F(ProgressTest, InvalidPath) {
1226 Progress progress("/devil/null");
1227 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1228}
1229
1230TEST_F(ProgressTest, EmptyFile) {
1231 Progress progress(CopyTextFileFixture("empty-file.txt"));
1232 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1233}
1234
1235TEST_F(ProgressTest, InvalidLine1stEntryNAN) {
1236 Progress progress(CopyTextFileFixture("stats-invalid-1st-NAN.txt"));
1237 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1238}
1239
1240TEST_F(ProgressTest, InvalidLine2ndEntryNAN) {
1241 Progress progress(CopyTextFileFixture("stats-invalid-2nd-NAN.txt"));
1242 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1243}
1244
1245TEST_F(ProgressTest, InvalidLineBothNAN) {
1246 Progress progress(CopyTextFileFixture("stats-invalid-both-NAN.txt"));
1247 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1248}
1249
1250TEST_F(ProgressTest, InvalidLine1stEntryNegative) {
1251 Progress progress(CopyTextFileFixture("stats-invalid-1st-negative.txt"));
1252 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1253}
1254
1255TEST_F(ProgressTest, InvalidLine2ndEntryNegative) {
1256 Progress progress(CopyTextFileFixture("stats-invalid-2nd-negative.txt"));
1257 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1258}
1259
1260TEST_F(ProgressTest, InvalidLine1stEntryTooBig) {
1261 Progress progress(CopyTextFileFixture("stats-invalid-1st-too-big.txt"));
1262 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1263}
1264
1265TEST_F(ProgressTest, InvalidLine2ndEntryTooBig) {
1266 Progress progress(CopyTextFileFixture("stats-invalid-2nd-too-big.txt"));
1267 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1268}
1269
1270// Tests stats are properly saved when the file does not exists.
1271TEST_F(ProgressTest, FirstTime) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001272 if (!IsStandalone()) {
1273 // TODO: temporarily disabled because it's failing when running as suite
1274 MYLOGE("Skipping ProgressTest.FirstTime() on test suite\n")
1275 return;
1276 }
1277
Felipe Leme7447d7c2016-11-03 18:12:22 -07001278 std::string path = kTestDataPath + "FirstTime.txt";
1279 android::base::RemoveFileIfExists(path);
1280
1281 Progress run1(path);
1282 EXPECT_EQ(0, run1.Get());
1283 EXPECT_EQ(Progress::kDefaultMax, run1.GetInitialMax());
1284 EXPECT_EQ(Progress::kDefaultMax, run1.GetMax());
1285
1286 bool max_increased = run1.Inc(20);
1287 EXPECT_EQ(20, run1.Get());
1288 EXPECT_EQ(Progress::kDefaultMax, run1.GetMax());
1289 EXPECT_FALSE(max_increased);
1290
1291 run1.Save();
1292 AssertStats(path, 1, 20);
1293}
1294
1295// Tests what happens when the persistent settings contains the average duration of 1 run.
1296// Data on file is 1 run and 109 average.
1297TEST_F(ProgressTest, SecondTime) {
1298 std::string path = CopyTextFileFixture("stats-one-run-no-newline.txt");
1299
1300 Progress run1 = GetInstance(-42, 1.2, path);
1301 EXPECT_EQ(0, run1.Get());
1302 EXPECT_EQ(10, run1.GetInitialMax());
1303 EXPECT_EQ(10, run1.GetMax());
1304
1305 bool max_increased = run1.Inc(20);
1306 EXPECT_EQ(20, run1.Get());
1307 EXPECT_EQ(24, run1.GetMax());
1308 EXPECT_TRUE(max_increased);
1309
1310 // Average now is 2 runs and (10 + 20)/ 2 = 15
1311 run1.Save();
1312 AssertStats(path, 2, 15);
1313
1314 Progress run2 = GetInstance(-42, 1.2, path);
1315 EXPECT_EQ(0, run2.Get());
1316 EXPECT_EQ(15, run2.GetInitialMax());
1317 EXPECT_EQ(15, run2.GetMax());
1318
1319 max_increased = run2.Inc(25);
1320 EXPECT_EQ(25, run2.Get());
1321 EXPECT_EQ(30, run2.GetMax());
1322 EXPECT_TRUE(max_increased);
1323
1324 // Average now is 3 runs and (15 * 2 + 25)/ 3 = 18.33 = 18
1325 run2.Save();
1326 AssertStats(path, 3, 18);
1327
1328 Progress run3 = GetInstance(-42, 1.2, path);
1329 EXPECT_EQ(0, run3.Get());
1330 EXPECT_EQ(18, run3.GetInitialMax());
1331 EXPECT_EQ(18, run3.GetMax());
1332
1333 // Make sure average decreases as well
1334 max_increased = run3.Inc(5);
1335 EXPECT_EQ(5, run3.Get());
1336 EXPECT_EQ(18, run3.GetMax());
1337 EXPECT_FALSE(max_increased);
1338
1339 // Average now is 4 runs and (18 * 3 + 5)/ 4 = 14.75 = 14
1340 run3.Save();
1341 AssertStats(path, 4, 14);
1342}
1343
1344// Tests what happens when the persistent settings contains the average duration of 2 runs.
1345// Data on file is 2 runs and 15 average.
1346TEST_F(ProgressTest, ThirdTime) {
1347 std::string path = CopyTextFileFixture("stats-two-runs.txt");
1348 AssertStats(path, 2, 15); // Sanity check
1349
1350 Progress run1 = GetInstance(-42, 1.2, path);
1351 EXPECT_EQ(0, run1.Get());
1352 EXPECT_EQ(15, run1.GetInitialMax());
1353 EXPECT_EQ(15, run1.GetMax());
1354
1355 bool max_increased = run1.Inc(20);
1356 EXPECT_EQ(20, run1.Get());
1357 EXPECT_EQ(24, run1.GetMax());
1358 EXPECT_TRUE(max_increased);
1359
1360 // Average now is 3 runs and (15 * 2 + 20)/ 3 = 16.66 = 16
1361 run1.Save();
1362 AssertStats(path, 3, 16);
1363}
1364
Felipe Leme46b85da2016-11-21 17:40:45 -08001365class DumpstateUtilTest : public DumpstateBaseTest {
1366 public:
1367 void SetUp() {
1368 DumpstateBaseTest::SetUp();
1369 SetDryRun(false);
1370 }
1371
Felipe Leme46b85da2016-11-21 17:40:45 -08001372 void CaptureFdOut() {
Felipe Lemef0292972016-11-22 13:57:05 -08001373 ReadFileToString(path_, &out);
Felipe Leme46b85da2016-11-21 17:40:45 -08001374 }
1375
1376 void CreateFd(const std::string& name) {
1377 path_ = kTestDataPath + name;
1378 MYLOGD("Creating fd for file %s\n", path_.c_str());
1379
1380 fd = TEMP_FAILURE_RETRY(open(path_.c_str(),
1381 O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW,
1382 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH));
1383 ASSERT_GE(fd, 0) << "could not create FD for path " << path_;
1384 }
1385
1386 // Runs a command into the `fd` and capture `stderr`.
Felipe Lemef0292972016-11-22 13:57:05 -08001387 int RunCommand(const std::string& title, const std::vector<std::string>& full_command,
Felipe Leme46b85da2016-11-21 17:40:45 -08001388 const CommandOptions& options = CommandOptions::DEFAULT) {
1389 CaptureStderr();
Felipe Lemef0292972016-11-22 13:57:05 -08001390 int status = RunCommandToFd(fd, title, full_command, options);
Felipe Leme46b85da2016-11-21 17:40:45 -08001391 close(fd);
1392
1393 CaptureFdOut();
1394 err = GetCapturedStderr();
1395 return status;
1396 }
1397
1398 // Dumps a file and into the `fd` and `stderr`.
Felipe Lemef0292972016-11-22 13:57:05 -08001399 int DumpFile(const std::string& title, const std::string& path) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001400 CaptureStderr();
Felipe Lemef0292972016-11-22 13:57:05 -08001401 int status = DumpFileToFd(fd, title, path);
Felipe Leme46b85da2016-11-21 17:40:45 -08001402 close(fd);
1403
1404 CaptureFdOut();
1405 err = GetCapturedStderr();
1406 return status;
1407 }
1408
1409 int fd;
1410
1411 // 'fd` output and `stderr` from the last command ran.
1412 std::string out, err;
1413
1414 private:
1415 std::string path_;
1416};
1417
1418TEST_F(DumpstateUtilTest, RunCommandNoArgs) {
Felipe Lemef0292972016-11-22 13:57:05 -08001419 CreateFd("RunCommandNoArgs.txt");
1420 EXPECT_EQ(-1, RunCommand("", {}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001421}
1422
Felipe Lemef0292972016-11-22 13:57:05 -08001423TEST_F(DumpstateUtilTest, RunCommandNoTitle) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001424 CreateFd("RunCommandWithNoArgs.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001425 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001426 EXPECT_THAT(out, StrEq("stdout\n"));
1427 EXPECT_THAT(err, StrEq("stderr\n"));
1428}
1429
Felipe Lemef0292972016-11-22 13:57:05 -08001430TEST_F(DumpstateUtilTest, RunCommandWithTitle) {
1431 CreateFd("RunCommandWithNoArgs.txt");
1432 EXPECT_EQ(0, RunCommand("I AM GROOT", {kSimpleCommand}));
1433 EXPECT_THAT(out, StrEq("------ I AM GROOT (" + kSimpleCommand + ") ------\nstdout\n"));
1434 EXPECT_THAT(err, StrEq("stderr\n"));
1435}
1436
Felipe Leme46b85da2016-11-21 17:40:45 -08001437TEST_F(DumpstateUtilTest, RunCommandWithOneArg) {
1438 CreateFd("RunCommandWithOneArg.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001439 EXPECT_EQ(0, RunCommand("", {kEchoCommand, "one"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001440 EXPECT_THAT(err, IsEmpty());
1441 EXPECT_THAT(out, StrEq("one\n"));
1442}
1443
1444TEST_F(DumpstateUtilTest, RunCommandWithMultipleArgs) {
1445 CreateFd("RunCommandWithMultipleArgs.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001446 EXPECT_EQ(0, RunCommand("", {kEchoCommand, "one", "is", "the", "loniest", "number"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001447 EXPECT_THAT(err, IsEmpty());
1448 EXPECT_THAT(out, StrEq("one is the loniest number\n"));
1449}
1450
1451TEST_F(DumpstateUtilTest, RunCommandWithLoggingMessage) {
1452 CreateFd("RunCommandWithLoggingMessage.txt");
1453 EXPECT_EQ(
Felipe Lemef0292972016-11-22 13:57:05 -08001454 0, RunCommand("", {kSimpleCommand},
Felipe Leme46b85da2016-11-21 17:40:45 -08001455 CommandOptions::WithTimeout(10).Log("COMMAND, Y U NO LOG FIRST?").Build()));
1456 EXPECT_THAT(out, StrEq("stdout\n"));
1457 EXPECT_THAT(err, StrEq("COMMAND, Y U NO LOG FIRST?stderr\n"));
1458}
1459
1460TEST_F(DumpstateUtilTest, RunCommandRedirectStderr) {
1461 CreateFd("RunCommandRedirectStderr.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001462 EXPECT_EQ(0, RunCommand("", {kSimpleCommand},
1463 CommandOptions::WithTimeout(10).RedirectStderr().Build()));
Felipe Leme46b85da2016-11-21 17:40:45 -08001464 EXPECT_THAT(out, IsEmpty());
1465 EXPECT_THAT(err, StrEq("stdout\nstderr\n"));
1466}
1467
1468TEST_F(DumpstateUtilTest, RunCommandDryRun) {
1469 CreateFd("RunCommandDryRun.txt");
1470 SetDryRun(true);
Felipe Lemef0292972016-11-22 13:57:05 -08001471 EXPECT_EQ(0, RunCommand("I AM GROOT", {kSimpleCommand}));
1472 EXPECT_THAT(out, StrEq(android::base::StringPrintf(
1473 "------ I AM GROOT (%s) ------\n\t(skipped on dry run)\n",
1474 kSimpleCommand.c_str())));
1475 EXPECT_THAT(err, IsEmpty());
1476}
1477
1478TEST_F(DumpstateUtilTest, RunCommandDryRunNoTitle) {
1479 CreateFd("RunCommandDryRun.txt");
1480 SetDryRun(true);
1481 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001482 EXPECT_THAT(
1483 out, StrEq(android::base::StringPrintf("%s: skipped on dry run\n", kSimpleCommand.c_str())));
1484 EXPECT_THAT(err, IsEmpty());
1485}
1486
1487TEST_F(DumpstateUtilTest, RunCommandDryRunAlways) {
1488 CreateFd("RunCommandDryRunAlways.txt");
1489 SetDryRun(true);
Felipe Lemef0292972016-11-22 13:57:05 -08001490 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(10).Always().Build()));
Felipe Leme46b85da2016-11-21 17:40:45 -08001491 EXPECT_THAT(out, StrEq("stdout\n"));
1492 EXPECT_THAT(err, StrEq("stderr\n"));
1493}
1494
1495TEST_F(DumpstateUtilTest, RunCommandNotFound) {
1496 CreateFd("RunCommandNotFound.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001497 EXPECT_NE(0, RunCommand("", {"/there/cannot/be/such/command"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001498 EXPECT_THAT(out, StartsWith("*** command '/there/cannot/be/such/command' failed: exit code"));
1499 EXPECT_THAT(err, StartsWith("execvp on command '/there/cannot/be/such/command' failed"));
1500}
1501
1502TEST_F(DumpstateUtilTest, RunCommandFails) {
1503 CreateFd("RunCommandFails.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001504 EXPECT_EQ(42, RunCommand("", {kSimpleCommand, "--exit", "42"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001505 EXPECT_THAT(out, StrEq("stdout\n*** command '" + kSimpleCommand +
1506 " --exit 42' failed: exit code 42\n"));
1507 EXPECT_THAT(err, StrEq("stderr\n*** command '" + kSimpleCommand +
1508 " --exit 42' failed: exit code 42\n"));
1509}
1510
1511TEST_F(DumpstateUtilTest, RunCommandCrashes) {
1512 CreateFd("RunCommandCrashes.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001513 EXPECT_NE(0, RunCommand("", {kSimpleCommand, "--crash"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001514 // We don't know the exit code, so check just the prefix.
1515 EXPECT_THAT(
1516 out, StartsWith("stdout\n*** command '" + kSimpleCommand + " --crash' failed: exit code"));
1517 EXPECT_THAT(
1518 err, StartsWith("stderr\n*** command '" + kSimpleCommand + " --crash' failed: exit code"));
1519}
1520
Vishnu Nair6921f802017-11-22 09:17:23 -08001521TEST_F(DumpstateUtilTest, RunCommandTimesoutWithSec) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001522 CreateFd("RunCommandTimesout.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001523 EXPECT_EQ(-1, RunCommand("", {kSimpleCommand, "--sleep", "2"},
1524 CommandOptions::WithTimeout(1).Build()));
Felipe Leme46b85da2016-11-21 17:40:45 -08001525 EXPECT_THAT(out, StartsWith("stdout line1\n*** command '" + kSimpleCommand +
1526 " --sleep 2' timed out after 1"));
1527 EXPECT_THAT(err, StartsWith("sleeping for 2s\n*** command '" + kSimpleCommand +
1528 " --sleep 2' timed out after 1"));
1529}
1530
Vishnu Nair6921f802017-11-22 09:17:23 -08001531TEST_F(DumpstateUtilTest, RunCommandTimesoutWithMsec) {
1532 CreateFd("RunCommandTimesout.txt");
1533 EXPECT_EQ(-1, RunCommand("", {kSimpleCommand, "--sleep", "2"},
1534 CommandOptions::WithTimeoutInMs(1000).Build()));
1535 EXPECT_THAT(out, StartsWith("stdout line1\n*** command '" + kSimpleCommand +
1536 " --sleep 2' timed out after 1"));
1537 EXPECT_THAT(err, StartsWith("sleeping for 2s\n*** command '" + kSimpleCommand +
1538 " --sleep 2' timed out after 1"));
1539}
1540
1541
Felipe Leme46b85da2016-11-21 17:40:45 -08001542TEST_F(DumpstateUtilTest, RunCommandIsKilled) {
1543 CreateFd("RunCommandIsKilled.txt");
1544 CaptureStderr();
1545
1546 std::thread t([=]() {
Felipe Lemef0292972016-11-22 13:57:05 -08001547 EXPECT_EQ(SIGTERM, RunCommandToFd(fd, "", {kSimpleCommand, "--pid", "--sleep", "20"},
Felipe Leme46b85da2016-11-21 17:40:45 -08001548 CommandOptions::WithTimeout(100).Always().Build()));
1549 });
1550
1551 // Capture pid and pre-sleep output.
1552 sleep(1); // Wait a little bit to make sure pid and 1st line were printed.
1553 std::string err = GetCapturedStderr();
1554 EXPECT_THAT(err, StrEq("sleeping for 20s\n"));
1555
1556 CaptureFdOut();
1557 std::vector<std::string> lines = android::base::Split(out, "\n");
1558 ASSERT_EQ(3, (int)lines.size()) << "Invalid lines before sleep: " << out;
1559
1560 int pid = atoi(lines[0].c_str());
1561 EXPECT_THAT(lines[1], StrEq("stdout line1"));
1562 EXPECT_THAT(lines[2], IsEmpty()); // \n
1563
1564 // Then kill the process.
1565 CaptureFdOut();
1566 CaptureStderr();
1567 ASSERT_EQ(0, kill(pid, SIGTERM)) << "failed to kill pid " << pid;
1568 t.join();
1569
1570 // Finally, check output after murder.
1571 CaptureFdOut();
1572 err = GetCapturedStderr();
1573
1574 // out starts with the pid, which is an unknown
1575 EXPECT_THAT(out, EndsWith("stdout line1\n*** command '" + kSimpleCommand +
1576 " --pid --sleep 20' failed: killed by signal 15\n"));
1577 EXPECT_THAT(err, StrEq("*** command '" + kSimpleCommand +
1578 " --pid --sleep 20' failed: killed by signal 15\n"));
1579}
1580
1581TEST_F(DumpstateUtilTest, RunCommandAsRootUserBuild) {
1582 if (!IsStandalone()) {
1583 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1584 // to Shell - need to refactor tests to avoid this problem)
1585 MYLOGE("Skipping DumpstateUtilTest.RunCommandAsRootUserBuild() on test suite\n")
1586 return;
1587 }
1588 CreateFd("RunCommandAsRootUserBuild.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001589 if (!PropertiesHelper::IsUserBuild()) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001590 // Emulates user build if necessarily.
1591 SetBuildType("user");
1592 }
1593
1594 DropRoot();
1595
Felipe Lemef0292972016-11-22 13:57:05 -08001596 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).AsRoot().Build()));
Felipe Leme46b85da2016-11-21 17:40:45 -08001597
1598 // We don't know the exact path of su, so we just check for the 'root ...' commands
1599 EXPECT_THAT(out, StartsWith("Skipping"));
1600 EXPECT_THAT(out, EndsWith("root " + kSimpleCommand + "' on user build.\n"));
1601 EXPECT_THAT(err, IsEmpty());
1602}
1603
1604TEST_F(DumpstateUtilTest, RunCommandAsRootNonUserBuild) {
1605 if (!IsStandalone()) {
1606 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1607 // to Shell - need to refactor tests to avoid this problem)
1608 MYLOGE("Skipping DumpstateUtilTest.RunCommandAsRootNonUserBuild() on test suite\n")
1609 return;
1610 }
1611 CreateFd("RunCommandAsRootNonUserBuild.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001612 if (PropertiesHelper::IsUserBuild()) {
Felipe Leme7447d7c2016-11-03 18:12:22 -07001613 ALOGI("Skipping RunCommandAsRootNonUserBuild on user builds\n");
1614 return;
1615 }
1616
1617 DropRoot();
1618
Felipe Lemef0292972016-11-22 13:57:05 -08001619 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
1620 CommandOptions::WithTimeout(1).AsRoot().Build()));
Felipe Leme7447d7c2016-11-03 18:12:22 -07001621
1622 EXPECT_THAT(out, StrEq("0\nstdout\n"));
1623 EXPECT_THAT(err, StrEq("stderr\n"));
1624}
Felipe Leme46b85da2016-11-21 17:40:45 -08001625
Yifan Hong48e83a12017-10-03 14:10:07 -07001626
1627TEST_F(DumpstateUtilTest, RunCommandAsRootIfAvailableOnUserBuild) {
1628 if (!IsStandalone()) {
1629 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1630 // to Shell - need to refactor tests to avoid this problem)
1631 MYLOGE("Skipping DumpstateUtilTest.RunCommandAsRootIfAvailableOnUserBuild() on test suite\n")
1632 return;
1633 }
1634 CreateFd("RunCommandAsRootIfAvailableOnUserBuild.txt");
1635 if (!PropertiesHelper::IsUserBuild()) {
1636 // Emulates user build if necessarily.
1637 SetBuildType("user");
1638 }
1639
1640 DropRoot();
1641
1642 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
1643 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
1644
1645 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
1646 EXPECT_THAT(err, StrEq("stderr\n"));
1647}
1648
1649TEST_F(DumpstateUtilTest, RunCommandAsRootIfAvailableOnDebugBuild) {
1650 if (!IsStandalone()) {
1651 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1652 // to Shell - need to refactor tests to avoid this problem)
1653 MYLOGE("Skipping DumpstateUtilTest.RunCommandAsRootIfAvailableOnDebugBuild() on test suite\n")
1654 return;
1655 }
1656 CreateFd("RunCommandAsRootIfAvailableOnDebugBuild.txt");
1657 if (PropertiesHelper::IsUserBuild()) {
1658 ALOGI("Skipping RunCommandAsRootNonUserBuild on user builds\n");
1659 return;
1660 }
1661
1662 DropRoot();
1663
1664 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
1665 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
1666
1667 EXPECT_THAT(out, StrEq("0\nstdout\n"));
1668 EXPECT_THAT(err, StrEq("stderr\n"));
1669}
1670
Felipe Leme46b85da2016-11-21 17:40:45 -08001671TEST_F(DumpstateUtilTest, RunCommandDropRoot) {
1672 if (!IsStandalone()) {
1673 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1674 // to Shell - need to refactor tests to avoid this problem)
1675 MYLOGE("Skipping DumpstateUtilTest.RunCommandDropRoot() on test suite\n")
1676 return;
1677 }
1678 CreateFd("RunCommandDropRoot.txt");
1679 // First check root case - only available when running with 'adb root'.
1680 uid_t uid = getuid();
1681 if (uid == 0) {
Felipe Lemef0292972016-11-22 13:57:05 -08001682 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001683 EXPECT_THAT(out, StrEq("0\nstdout\n"));
1684 EXPECT_THAT(err, StrEq("stderr\n"));
1685 return;
1686 }
1687 // Then run dropping root.
Felipe Lemef0292972016-11-22 13:57:05 -08001688 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
Felipe Leme46b85da2016-11-21 17:40:45 -08001689 CommandOptions::WithTimeout(1).DropRoot().Build()));
1690 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
1691 EXPECT_THAT(err, StrEq("drop_root_user(): already running as Shell\nstderr\n"));
1692}
1693
Felipe Lemef0292972016-11-22 13:57:05 -08001694TEST_F(DumpstateUtilTest, DumpFileNotFoundNoTitle) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001695 CreateFd("DumpFileNotFound.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001696 EXPECT_EQ(-1, DumpFile("", "/I/cant/believe/I/exist"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001697 EXPECT_THAT(out,
1698 StrEq("*** Error dumping /I/cant/believe/I/exist: No such file or directory\n"));
1699 EXPECT_THAT(err, IsEmpty());
1700}
1701
Felipe Lemef0292972016-11-22 13:57:05 -08001702TEST_F(DumpstateUtilTest, DumpFileNotFoundWithTitle) {
1703 CreateFd("DumpFileNotFound.txt");
1704 EXPECT_EQ(-1, DumpFile("Y U NO EXIST?", "/I/cant/believe/I/exist"));
1705 EXPECT_THAT(out, StrEq("*** Error dumping /I/cant/believe/I/exist (Y U NO EXIST?): No such "
1706 "file or directory\n"));
1707 EXPECT_THAT(err, IsEmpty());
1708}
1709
Felipe Leme46b85da2016-11-21 17:40:45 -08001710TEST_F(DumpstateUtilTest, DumpFileSingleLine) {
1711 CreateFd("DumpFileSingleLine.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001712 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001713 EXPECT_THAT(err, IsEmpty());
1714 EXPECT_THAT(out, StrEq("I AM LINE1\n")); // dumpstate adds missing newline
1715}
1716
1717TEST_F(DumpstateUtilTest, DumpFileSingleLineWithNewLine) {
1718 CreateFd("DumpFileSingleLineWithNewLine.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001719 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line-with-newline.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001720 EXPECT_THAT(err, IsEmpty());
1721 EXPECT_THAT(out, StrEq("I AM LINE1\n"));
1722}
1723
1724TEST_F(DumpstateUtilTest, DumpFileMultipleLines) {
1725 CreateFd("DumpFileMultipleLines.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001726 EXPECT_EQ(0, DumpFile("", kTestDataPath + "multiple-lines.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001727 EXPECT_THAT(err, IsEmpty());
1728 EXPECT_THAT(out, StrEq("I AM LINE1\nI AM LINE2\nI AM LINE3\n"));
1729}
1730
1731TEST_F(DumpstateUtilTest, DumpFileMultipleLinesWithNewLine) {
1732 CreateFd("DumpFileMultipleLinesWithNewLine.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001733 EXPECT_EQ(0, DumpFile("", kTestDataPath + "multiple-lines-with-newline.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001734 EXPECT_THAT(err, IsEmpty());
1735 EXPECT_THAT(out, StrEq("I AM LINE1\nI AM LINE2\nI AM LINE3\n"));
1736}
1737
Felipe Lemef0292972016-11-22 13:57:05 -08001738TEST_F(DumpstateUtilTest, DumpFileOnDryRunNoTitle) {
1739 CreateFd("DumpFileOnDryRun.txt");
1740 SetDryRun(true);
1741 std::string path = kTestDataPath + "single-line.txt";
1742 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
1743 EXPECT_THAT(err, IsEmpty());
1744 EXPECT_THAT(out, StrEq(path + ": skipped on dry run\n"));
1745}
1746
Felipe Leme46b85da2016-11-21 17:40:45 -08001747TEST_F(DumpstateUtilTest, DumpFileOnDryRun) {
1748 CreateFd("DumpFileOnDryRun.txt");
1749 SetDryRun(true);
1750 std::string path = kTestDataPath + "single-line.txt";
Felipe Lemef0292972016-11-22 13:57:05 -08001751 EXPECT_EQ(0, DumpFile("Might as well dump. Dump!", kTestDataPath + "single-line.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001752 EXPECT_THAT(err, IsEmpty());
Felipe Lemef0292972016-11-22 13:57:05 -08001753 EXPECT_THAT(
1754 out, StartsWith("------ Might as well dump. Dump! (" + kTestDataPath + "single-line.txt:"));
1755 EXPECT_THAT(out, EndsWith("skipped on dry run\n"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001756}
Ecco Park61ffcf72016-10-27 15:46:26 -07001757
Felipe Leme47e9be22016-12-21 15:37:07 -08001758} // namespace dumpstate
1759} // namespace os
1760} // namespace android