blob: 71d15f4761803aae6499e8435979fc3384942c52 [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);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100175 EXPECT_FALSE(options_.use_socket);
176 EXPECT_FALSE(options_.use_control_socket);
177 EXPECT_FALSE(options_.show_header_only);
178 EXPECT_TRUE(options_.do_vibrate);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000179 EXPECT_FALSE(options_.do_fb);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100180 EXPECT_FALSE(options_.do_progress_updates);
181 EXPECT_FALSE(options_.is_remote_mode);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000182 EXPECT_FALSE(options_.do_broadcast);
183}
184
185TEST_F(DumpOptionsTest, InitializeAdbBugreport) {
186 // clang-format off
187 char* argv[] = {
188 const_cast<char*>("dumpstatez"),
189 const_cast<char*>("-S"),
190 const_cast<char*>("-d"),
191 const_cast<char*>("-z"),
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000192 };
193 // clang-format on
194
195 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
196
197 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
198 EXPECT_TRUE(options_.do_add_date);
199 EXPECT_TRUE(options_.do_zip_file);
200 EXPECT_TRUE(options_.use_control_socket);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000201
202 // Other options retain default values
203 EXPECT_TRUE(options_.do_vibrate);
204 EXPECT_FALSE(options_.show_header_only);
205 EXPECT_FALSE(options_.do_fb);
206 EXPECT_FALSE(options_.do_progress_updates);
207 EXPECT_FALSE(options_.is_remote_mode);
208 EXPECT_FALSE(options_.do_broadcast);
209 EXPECT_FALSE(options_.use_socket);
210}
211
212TEST_F(DumpOptionsTest, InitializeAdbShellBugreport) {
213 // clang-format off
214 char* argv[] = {
215 const_cast<char*>("dumpstate"),
216 const_cast<char*>("-s"),
217 };
218 // clang-format on
219
220 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
221
222 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
223 EXPECT_TRUE(options_.use_socket);
224
225 // Other options retain default values
226 EXPECT_TRUE(options_.do_vibrate);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000227 EXPECT_FALSE(options_.do_add_date);
228 EXPECT_FALSE(options_.do_zip_file);
229 EXPECT_FALSE(options_.use_control_socket);
230 EXPECT_FALSE(options_.show_header_only);
231 EXPECT_FALSE(options_.do_fb);
232 EXPECT_FALSE(options_.do_progress_updates);
233 EXPECT_FALSE(options_.is_remote_mode);
234 EXPECT_FALSE(options_.do_broadcast);
235}
236
237TEST_F(DumpOptionsTest, InitializeFullBugReport) {
238 // clang-format off
239 char* argv[] = {
240 const_cast<char*>("bugreport"),
241 const_cast<char*>("-d"),
242 const_cast<char*>("-p"),
243 const_cast<char*>("-B"),
244 const_cast<char*>("-z"),
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000245 };
246 // clang-format on
247 property_set("dumpstate.options", "bugreportfull");
248
249 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
250
251 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
252 EXPECT_TRUE(options_.do_add_date);
253 EXPECT_TRUE(options_.do_fb);
254 EXPECT_TRUE(options_.do_zip_file);
Nandana Dutt58d72e22018-11-16 10:30:48 +0000255 EXPECT_TRUE(options_.do_broadcast);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000256
257 // Other options retain default values
258 EXPECT_TRUE(options_.do_vibrate);
259 EXPECT_FALSE(options_.use_control_socket);
260 EXPECT_FALSE(options_.show_header_only);
261 EXPECT_FALSE(options_.do_progress_updates);
262 EXPECT_FALSE(options_.is_remote_mode);
263 EXPECT_FALSE(options_.use_socket);
264 EXPECT_FALSE(options_.do_start_service);
265}
266
267TEST_F(DumpOptionsTest, InitializeInteractiveBugReport) {
268 // clang-format off
269 char* argv[] = {
270 const_cast<char*>("bugreport"),
271 const_cast<char*>("-d"),
272 const_cast<char*>("-p"),
273 const_cast<char*>("-B"),
274 const_cast<char*>("-z"),
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000275 };
276 // clang-format on
277
278 property_set("dumpstate.options", "bugreportplus");
279
280 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
281
282 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
283 EXPECT_TRUE(options_.do_add_date);
284 EXPECT_TRUE(options_.do_broadcast);
285 EXPECT_TRUE(options_.do_zip_file);
286 EXPECT_TRUE(options_.do_progress_updates);
287 EXPECT_TRUE(options_.do_start_service);
288 EXPECT_FALSE(options_.do_fb);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000289
290 // Other options retain default values
291 EXPECT_TRUE(options_.do_vibrate);
292 EXPECT_FALSE(options_.use_control_socket);
293 EXPECT_FALSE(options_.show_header_only);
294 EXPECT_FALSE(options_.is_remote_mode);
295 EXPECT_FALSE(options_.use_socket);
296}
297
298TEST_F(DumpOptionsTest, InitializeRemoteBugReport) {
299 // clang-format off
300 char* argv[] = {
301 const_cast<char*>("bugreport"),
302 const_cast<char*>("-d"),
303 const_cast<char*>("-p"),
304 const_cast<char*>("-B"),
305 const_cast<char*>("-z"),
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000306 };
307 // clang-format on
308
309 property_set("dumpstate.options", "bugreportremote");
310
311 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
312
313 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
314 EXPECT_TRUE(options_.do_add_date);
315 EXPECT_TRUE(options_.do_broadcast);
316 EXPECT_TRUE(options_.do_zip_file);
317 EXPECT_TRUE(options_.is_remote_mode);
318 EXPECT_FALSE(options_.do_vibrate);
319 EXPECT_FALSE(options_.do_fb);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000320
321 // Other options retain default values
322 EXPECT_FALSE(options_.use_control_socket);
323 EXPECT_FALSE(options_.show_header_only);
324 EXPECT_FALSE(options_.do_progress_updates);
325 EXPECT_FALSE(options_.use_socket);
326}
327
328TEST_F(DumpOptionsTest, InitializeWearBugReport) {
329 // clang-format off
330 char* argv[] = {
331 const_cast<char*>("bugreport"),
332 const_cast<char*>("-d"),
333 const_cast<char*>("-p"),
334 const_cast<char*>("-B"),
335 const_cast<char*>("-z"),
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000336 };
337 // clang-format on
338
339 property_set("dumpstate.options", "bugreportwear");
340
341 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
342
343 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
344 EXPECT_TRUE(options_.do_add_date);
345 EXPECT_TRUE(options_.do_fb);
346 EXPECT_TRUE(options_.do_broadcast);
347 EXPECT_TRUE(options_.do_zip_file);
348 EXPECT_TRUE(options_.do_progress_updates);
349 EXPECT_TRUE(options_.do_start_service);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000350
351 // Other options retain default values
352 EXPECT_TRUE(options_.do_vibrate);
353 EXPECT_FALSE(options_.use_control_socket);
354 EXPECT_FALSE(options_.show_header_only);
355 EXPECT_FALSE(options_.is_remote_mode);
356 EXPECT_FALSE(options_.use_socket);
357}
358
359TEST_F(DumpOptionsTest, InitializeTelephonyBugReport) {
360 // clang-format off
361 char* argv[] = {
362 const_cast<char*>("bugreport"),
363 const_cast<char*>("-d"),
364 const_cast<char*>("-p"),
365 const_cast<char*>("-B"),
366 const_cast<char*>("-z"),
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000367 };
368 // clang-format on
369
370 property_set("dumpstate.options", "bugreporttelephony");
371
372 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
373
374 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
375 EXPECT_TRUE(options_.do_add_date);
Abhijeet Kaurd3cca0d2019-03-25 12:04:16 +0000376 EXPECT_FALSE(options_.do_fb);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000377 EXPECT_TRUE(options_.do_broadcast);
378 EXPECT_TRUE(options_.do_zip_file);
379 EXPECT_TRUE(options_.telephony_only);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000380
381 // Other options retain default values
382 EXPECT_TRUE(options_.do_vibrate);
383 EXPECT_FALSE(options_.use_control_socket);
384 EXPECT_FALSE(options_.show_header_only);
385 EXPECT_FALSE(options_.do_progress_updates);
386 EXPECT_FALSE(options_.is_remote_mode);
387 EXPECT_FALSE(options_.use_socket);
388}
389
390TEST_F(DumpOptionsTest, InitializeWifiBugReport) {
391 // clang-format off
392 char* argv[] = {
393 const_cast<char*>("bugreport"),
394 const_cast<char*>("-d"),
395 const_cast<char*>("-p"),
396 const_cast<char*>("-B"),
397 const_cast<char*>("-z"),
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000398 };
399 // clang-format on
400
401 property_set("dumpstate.options", "bugreportwifi");
402
403 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
404
405 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
406 EXPECT_TRUE(options_.do_add_date);
Abhijeet Kaurd3cca0d2019-03-25 12:04:16 +0000407 EXPECT_FALSE(options_.do_fb);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000408 EXPECT_TRUE(options_.do_broadcast);
409 EXPECT_TRUE(options_.do_zip_file);
410 EXPECT_TRUE(options_.wifi_only);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000411
412 // Other options retain default values
413 EXPECT_TRUE(options_.do_vibrate);
414 EXPECT_FALSE(options_.use_control_socket);
415 EXPECT_FALSE(options_.show_header_only);
416 EXPECT_FALSE(options_.do_progress_updates);
417 EXPECT_FALSE(options_.is_remote_mode);
418 EXPECT_FALSE(options_.use_socket);
419}
420
421TEST_F(DumpOptionsTest, InitializeDefaultBugReport) {
422 // default: commandline options are not overridden
423 // clang-format off
424 char* argv[] = {
425 const_cast<char*>("bugreport"),
426 const_cast<char*>("-d"),
427 const_cast<char*>("-p"),
428 const_cast<char*>("-B"),
429 const_cast<char*>("-z"),
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000430 };
431 // clang-format on
432
433 property_set("dumpstate.options", "");
434
435 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
436
437 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
438 EXPECT_TRUE(options_.do_add_date);
439 EXPECT_TRUE(options_.do_fb);
440 EXPECT_TRUE(options_.do_zip_file);
441 EXPECT_TRUE(options_.do_broadcast);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000442
443 // Other options retain default values
444 EXPECT_TRUE(options_.do_vibrate);
445 EXPECT_FALSE(options_.use_control_socket);
446 EXPECT_FALSE(options_.show_header_only);
447 EXPECT_FALSE(options_.do_progress_updates);
448 EXPECT_FALSE(options_.is_remote_mode);
449 EXPECT_FALSE(options_.use_socket);
450 EXPECT_FALSE(options_.wifi_only);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100451}
452
453TEST_F(DumpOptionsTest, InitializePartial1) {
454 // clang-format off
455 char* argv[] = {
456 const_cast<char*>("dumpstate"),
457 const_cast<char*>("-d"),
458 const_cast<char*>("-z"),
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100459 const_cast<char*>("-s"),
460 const_cast<char*>("-S"),
461
462 };
463 // clang-format on
464
465 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
466
467 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
468 EXPECT_TRUE(options_.do_add_date);
469 EXPECT_TRUE(options_.do_zip_file);
470 // TODO: Maybe we should trim the filename
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100471 EXPECT_TRUE(options_.use_socket);
472 EXPECT_TRUE(options_.use_control_socket);
473
474 // Other options retain default values
475 EXPECT_FALSE(options_.show_header_only);
476 EXPECT_TRUE(options_.do_vibrate);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000477 EXPECT_FALSE(options_.do_fb);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100478 EXPECT_FALSE(options_.do_progress_updates);
479 EXPECT_FALSE(options_.is_remote_mode);
Abhijeet Kaur904e0e02018-12-05 14:03:01 +0000480 EXPECT_FALSE(options_.do_broadcast);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100481}
482
483TEST_F(DumpOptionsTest, InitializePartial2) {
484 // clang-format off
485 char* argv[] = {
486 const_cast<char*>("dumpstate"),
487 const_cast<char*>("-v"),
488 const_cast<char*>("-q"),
489 const_cast<char*>("-p"),
490 const_cast<char*>("-P"),
491 const_cast<char*>("-R"),
492 const_cast<char*>("-B"),
493 };
494 // clang-format on
495
496 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
497
498 EXPECT_EQ(status, Dumpstate::RunStatus::OK);
499 EXPECT_TRUE(options_.show_header_only);
500 EXPECT_FALSE(options_.do_vibrate);
501 EXPECT_TRUE(options_.do_fb);
502 EXPECT_TRUE(options_.do_progress_updates);
503 EXPECT_TRUE(options_.is_remote_mode);
504 EXPECT_TRUE(options_.do_broadcast);
505
506 // Other options retain default values
507 EXPECT_FALSE(options_.do_add_date);
508 EXPECT_FALSE(options_.do_zip_file);
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100509 EXPECT_FALSE(options_.use_socket);
510 EXPECT_FALSE(options_.use_control_socket);
511}
512
513TEST_F(DumpOptionsTest, InitializeHelp) {
514 // clang-format off
515 char* argv[] = {
516 const_cast<char*>("dumpstate"),
517 const_cast<char*>("-h")
518 };
519 // clang-format on
520
521 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
522
523 // -h is for help.
524 EXPECT_EQ(status, Dumpstate::RunStatus::HELP);
525}
526
527TEST_F(DumpOptionsTest, InitializeUnknown) {
528 // clang-format off
529 char* argv[] = {
530 const_cast<char*>("dumpstate"),
531 const_cast<char*>("-u") // unknown flag
532 };
533 // clang-format on
534
535 Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
536
537 // -u is unknown.
538 EXPECT_EQ(status, Dumpstate::RunStatus::INVALID_INPUT);
539}
540
541TEST_F(DumpOptionsTest, ValidateOptionsNeedOutfile1) {
542 options_.do_zip_file = true;
Nandana Dutt9a76d202019-01-21 15:56:48 +0000543 // Writing to socket = !writing to file.
544 options_.use_socket = true;
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100545 EXPECT_FALSE(options_.ValidateOptions());
Nandana Dutt9a76d202019-01-21 15:56:48 +0000546
547 options_.use_socket = false;
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100548 EXPECT_TRUE(options_.ValidateOptions());
549}
550
551TEST_F(DumpOptionsTest, ValidateOptionsNeedOutfile2) {
552 options_.do_broadcast = true;
Nandana Dutt9a76d202019-01-21 15:56:48 +0000553 // Writing to socket = !writing to file.
554 options_.use_socket = true;
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100555 EXPECT_FALSE(options_.ValidateOptions());
Nandana Dutt9a76d202019-01-21 15:56:48 +0000556
557 options_.use_socket = false;
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100558 EXPECT_TRUE(options_.ValidateOptions());
559}
560
561TEST_F(DumpOptionsTest, ValidateOptionsNeedZipfile) {
562 options_.use_control_socket = true;
563 EXPECT_FALSE(options_.ValidateOptions());
564
565 options_.do_zip_file = true;
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100566 EXPECT_TRUE(options_.ValidateOptions());
567}
568
569TEST_F(DumpOptionsTest, ValidateOptionsUpdateProgressNeedsBroadcast) {
570 options_.do_progress_updates = true;
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100571 EXPECT_FALSE(options_.ValidateOptions());
572
573 options_.do_broadcast = true;
574 EXPECT_TRUE(options_.ValidateOptions());
575}
576
577TEST_F(DumpOptionsTest, ValidateOptionsRemoteMode) {
578 options_.is_remote_mode = true;
579 EXPECT_FALSE(options_.ValidateOptions());
580
581 options_.do_broadcast = true;
582 options_.do_zip_file = true;
583 options_.do_add_date = true;
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100584 EXPECT_TRUE(options_.ValidateOptions());
585}
586
Felipe Leme7447d7c2016-11-03 18:12:22 -0700587class DumpstateTest : public DumpstateBaseTest {
Felipe Leme4c2d6632016-09-28 14:32:00 -0700588 public:
589 void SetUp() {
Felipe Leme46b85da2016-11-21 17:40:45 -0800590 DumpstateBaseTest::SetUp();
Felipe Leme4c2d6632016-09-28 14:32:00 -0700591 SetDryRun(false);
Felipe Lemed80e6b62016-10-03 13:08:14 -0700592 SetBuildType(android::base::GetProperty("ro.build.type", "(unknown)"));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700593 ds.progress_.reset(new Progress());
Felipe Leme009ecbb2016-11-07 10:18:44 -0800594 ds.update_progress_threshold_ = 0;
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100595 ds.options_.reset(new Dumpstate::DumpOptions());
Felipe Leme4c2d6632016-09-28 14:32:00 -0700596 }
597
598 // Runs a command and capture `stdout` and `stderr`.
Felipe Leme9a523ae2016-10-20 15:10:33 -0700599 int RunCommand(const std::string& title, const std::vector<std::string>& full_command,
Felipe Leme4c2d6632016-09-28 14:32:00 -0700600 const CommandOptions& options = CommandOptions::DEFAULT) {
601 CaptureStdout();
602 CaptureStderr();
Felipe Leme9a523ae2016-10-20 15:10:33 -0700603 int status = ds.RunCommand(title, full_command, options);
Felipe Leme4c2d6632016-09-28 14:32:00 -0700604 out = GetCapturedStdout();
605 err = GetCapturedStderr();
606 return status;
607 }
608
Felipe Lemecef02982016-10-03 17:22:22 -0700609 // Dumps a file and capture `stdout` and `stderr`.
610 int DumpFile(const std::string& title, const std::string& path) {
611 CaptureStdout();
612 CaptureStderr();
613 int status = ds.DumpFile(title, path);
614 out = GetCapturedStdout();
615 err = GetCapturedStderr();
616 return status;
617 }
618
Felipe Leme009ecbb2016-11-07 10:18:44 -0800619 void SetProgress(long progress, long initial_max, long threshold = 0) {
Nandana Dutt5fb117b2018-09-27 09:23:36 +0100620 ds.options_->do_progress_updates = true;
Felipe Leme009ecbb2016-11-07 10:18:44 -0800621 ds.update_progress_threshold_ = threshold;
622 ds.last_updated_progress_ = 0;
Felipe Leme7447d7c2016-11-03 18:12:22 -0700623 ds.progress_.reset(new Progress(initial_max, progress, 1.2));
624 }
625
Felipe Leme7447d7c2016-11-03 18:12:22 -0700626 std::string GetProgressMessage(const std::string& listener_name, int progress, int max,
Felipe Leme009ecbb2016-11-07 10:18:44 -0800627 int old_max = 0, bool update_progress = true) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700628 EXPECT_EQ(progress, ds.progress_->Get()) << "invalid progress";
629 EXPECT_EQ(max, ds.progress_->GetMax()) << "invalid max";
Felipe Leme75876a22016-10-27 16:31:27 -0700630
Felipe Leme7447d7c2016-11-03 18:12:22 -0700631 bool max_increased = old_max > 0;
Felipe Leme75876a22016-10-27 16:31:27 -0700632
Felipe Leme009ecbb2016-11-07 10:18:44 -0800633 std::string message = "";
Felipe Leme75876a22016-10-27 16:31:27 -0700634 if (max_increased) {
Felipe Leme009ecbb2016-11-07 10:18:44 -0800635 message =
Felipe Leme7447d7c2016-11-03 18:12:22 -0700636 android::base::StringPrintf("Adjusting max progress from %d to %d\n", old_max, max);
Felipe Leme75876a22016-10-27 16:31:27 -0700637 }
638
Felipe Leme009ecbb2016-11-07 10:18:44 -0800639 if (update_progress) {
Nandana Duttbabf6c72019-01-15 14:11:12 +0000640 message += android::base::StringPrintf("Setting progress (%s): %d/%d (%d%%)\n",
641 listener_name.c_str(), progress, max,
642 (100 * progress / max));
Felipe Leme009ecbb2016-11-07 10:18:44 -0800643 }
644
645 return message;
Felipe Lemed80e6b62016-10-03 13:08:14 -0700646 }
647
Felipe Leme4c2d6632016-09-28 14:32:00 -0700648 // `stdout` and `stderr` from the last command ran.
649 std::string out, err;
650
Felipe Lemefd8affa2016-09-30 17:38:57 -0700651 Dumpstate& ds = Dumpstate::GetInstance();
Felipe Leme4c2d6632016-09-28 14:32:00 -0700652};
653
654TEST_F(DumpstateTest, RunCommandNoArgs) {
655 EXPECT_EQ(-1, RunCommand("", {}));
656}
657
658TEST_F(DumpstateTest, RunCommandNoTitle) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700659 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700660 EXPECT_THAT(out, StrEq("stdout\n"));
661 EXPECT_THAT(err, StrEq("stderr\n"));
662}
663
664TEST_F(DumpstateTest, RunCommandWithTitle) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700665 EXPECT_EQ(0, RunCommand("I AM GROOT", {kSimpleCommand}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700666 EXPECT_THAT(err, StrEq("stderr\n"));
667 // We don't know the exact duration, so we check the prefix and suffix
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}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700702 // We don't know the exact duration, so we check the prefix and suffix
Felipe Leme7447d7c2016-11-03 18:12:22 -0700703 EXPECT_THAT(out, StartsWith("------ I AM GROOT (" + kSimpleCommand +
Nandana Dutt47527b52019-03-29 15:34:36 +0000704 ") ------\n\t(skipped on dry run)\n"));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700705 EXPECT_THAT(err, IsEmpty());
706}
707
708TEST_F(DumpstateTest, RunCommandDryRunNoTitle) {
709 SetDryRun(true);
Felipe Leme7447d7c2016-11-03 18:12:22 -0700710 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700711 EXPECT_THAT(out, IsEmpty());
712 EXPECT_THAT(err, IsEmpty());
713}
714
715TEST_F(DumpstateTest, RunCommandDryRunAlways) {
716 SetDryRun(true);
Felipe Leme7447d7c2016-11-03 18:12:22 -0700717 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(10).Always().Build()));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700718 EXPECT_THAT(out, StrEq("stdout\n"));
719 EXPECT_THAT(err, StrEq("stderr\n"));
720}
721
Felipe Lemefd8affa2016-09-30 17:38:57 -0700722TEST_F(DumpstateTest, RunCommandNotFound) {
723 EXPECT_NE(0, RunCommand("", {"/there/cannot/be/such/command"}));
724 EXPECT_THAT(out, StartsWith("*** command '/there/cannot/be/such/command' failed: exit code"));
725 EXPECT_THAT(err, StartsWith("execvp on command '/there/cannot/be/such/command' failed"));
726}
727
728TEST_F(DumpstateTest, RunCommandFails) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700729 EXPECT_EQ(42, RunCommand("", {kSimpleCommand, "--exit", "42"}));
730 EXPECT_THAT(out, StrEq("stdout\n*** command '" + kSimpleCommand +
Felipe Leme9a523ae2016-10-20 15:10:33 -0700731 " --exit 42' failed: exit code 42\n"));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700732 EXPECT_THAT(err, StrEq("stderr\n*** command '" + kSimpleCommand +
Felipe Leme9a523ae2016-10-20 15:10:33 -0700733 " --exit 42' failed: exit code 42\n"));
Felipe Lemefd8affa2016-09-30 17:38:57 -0700734}
735
736TEST_F(DumpstateTest, RunCommandCrashes) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700737 EXPECT_NE(0, RunCommand("", {kSimpleCommand, "--crash"}));
Felipe Lemefd8affa2016-09-30 17:38:57 -0700738 // We don't know the exit code, so check just the prefix.
739 EXPECT_THAT(
Felipe Leme7447d7c2016-11-03 18:12:22 -0700740 out, StartsWith("stdout\n*** command '" + kSimpleCommand + " --crash' failed: exit code"));
Felipe Lemefd8affa2016-09-30 17:38:57 -0700741 EXPECT_THAT(
Felipe Leme7447d7c2016-11-03 18:12:22 -0700742 err, StartsWith("stderr\n*** command '" + kSimpleCommand + " --crash' failed: exit code"));
Felipe Lemefd8affa2016-09-30 17:38:57 -0700743}
744
745TEST_F(DumpstateTest, RunCommandTimesout) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700746 EXPECT_EQ(-1, RunCommand("", {kSimpleCommand, "--sleep", "2"},
Felipe Lemefd8affa2016-09-30 17:38:57 -0700747 CommandOptions::WithTimeout(1).Build()));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700748 EXPECT_THAT(out, StartsWith("stdout line1\n*** command '" + kSimpleCommand +
Felipe Lemefd8affa2016-09-30 17:38:57 -0700749 " --sleep 2' timed out after 1"));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700750 EXPECT_THAT(err, StartsWith("sleeping for 2s\n*** command '" + kSimpleCommand +
Felipe Lemefd8affa2016-09-30 17:38:57 -0700751 " --sleep 2' timed out after 1"));
752}
753
754TEST_F(DumpstateTest, RunCommandIsKilled) {
755 CaptureStdout();
756 CaptureStderr();
757
758 std::thread t([=]() {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700759 EXPECT_EQ(SIGTERM, ds.RunCommand("", {kSimpleCommand, "--pid", "--sleep", "20"},
Felipe Lemefd8affa2016-09-30 17:38:57 -0700760 CommandOptions::WithTimeout(100).Always().Build()));
761 });
762
763 // Capture pid and pre-sleep output.
764 sleep(1); // Wait a little bit to make sure pid and 1st line were printed.
765 std::string err = GetCapturedStderr();
766 EXPECT_THAT(err, StrEq("sleeping for 20s\n"));
767
768 std::string out = GetCapturedStdout();
769 std::vector<std::string> lines = android::base::Split(out, "\n");
770 ASSERT_EQ(3, (int)lines.size()) << "Invalid lines before sleep: " << out;
771
772 int pid = atoi(lines[0].c_str());
773 EXPECT_THAT(lines[1], StrEq("stdout line1"));
774 EXPECT_THAT(lines[2], IsEmpty()); // \n
775
776 // Then kill the process.
777 CaptureStdout();
778 CaptureStderr();
779 ASSERT_EQ(0, kill(pid, SIGTERM)) << "failed to kill pid " << pid;
780 t.join();
781
782 // Finally, check output after murder.
783 out = GetCapturedStdout();
784 err = GetCapturedStderr();
785
Felipe Leme7447d7c2016-11-03 18:12:22 -0700786 EXPECT_THAT(out, StrEq("*** command '" + kSimpleCommand +
Felipe Lemefd8affa2016-09-30 17:38:57 -0700787 " --pid --sleep 20' failed: killed by signal 15\n"));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700788 EXPECT_THAT(err, StrEq("*** command '" + kSimpleCommand +
Felipe Lemefd8affa2016-09-30 17:38:57 -0700789 " --pid --sleep 20' failed: killed by signal 15\n"));
790}
791
Felipe Leme75876a22016-10-27 16:31:27 -0700792TEST_F(DumpstateTest, RunCommandProgress) {
793 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
794 ds.listener_ = listener;
795 ds.listener_name_ = "FoxMulder";
Felipe Leme7447d7c2016-11-03 18:12:22 -0700796 SetProgress(0, 30);
Felipe Leme75876a22016-10-27 16:31:27 -0700797
798 EXPECT_CALL(*listener, onProgressUpdated(20));
Nandana Duttbabf6c72019-01-15 14:11:12 +0000799 EXPECT_CALL(*listener, onProgress(66)); // 20/30 %
Felipe Leme7447d7c2016-11-03 18:12:22 -0700800 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(20).Build()));
Felipe Leme75876a22016-10-27 16:31:27 -0700801 std::string progress_message = GetProgressMessage(ds.listener_name_, 20, 30);
802 EXPECT_THAT(out, StrEq("stdout\n"));
803 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
804
805 EXPECT_CALL(*listener, onProgressUpdated(30));
Nandana Duttbabf6c72019-01-15 14:11:12 +0000806 EXPECT_CALL(*listener, onProgress(100)); // 35/35 %
Felipe Leme7447d7c2016-11-03 18:12:22 -0700807 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(10).Build()));
Felipe Leme75876a22016-10-27 16:31:27 -0700808 progress_message = GetProgressMessage(ds.listener_name_, 30, 30);
809 EXPECT_THAT(out, StrEq("stdout\n"));
810 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
811
812 // Run a command that will increase maximum timeout.
813 EXPECT_CALL(*listener, onProgressUpdated(31));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700814 EXPECT_CALL(*listener, onMaxProgressUpdated(37));
Nandana Duttbabf6c72019-01-15 14:11:12 +0000815 EXPECT_CALL(*listener, onProgress(83)); // 31/37 %
Felipe Leme7447d7c2016-11-03 18:12:22 -0700816 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).Build()));
817 progress_message = GetProgressMessage(ds.listener_name_, 31, 37, 30); // 20% increase
Felipe Leme75876a22016-10-27 16:31:27 -0700818 EXPECT_THAT(out, StrEq("stdout\n"));
819 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
820
821 // Make sure command ran while in dry_run is counted.
822 SetDryRun(true);
823 EXPECT_CALL(*listener, onProgressUpdated(35));
Nandana Duttbabf6c72019-01-15 14:11:12 +0000824 EXPECT_CALL(*listener, onProgress(94)); // 35/37 %
Felipe Leme7447d7c2016-11-03 18:12:22 -0700825 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(4).Build()));
826 progress_message = GetProgressMessage(ds.listener_name_, 35, 37);
Felipe Leme75876a22016-10-27 16:31:27 -0700827 EXPECT_THAT(out, IsEmpty());
828 EXPECT_THAT(err, StrEq(progress_message));
829
830 ds.listener_.clear();
831}
832
Felipe Leme009ecbb2016-11-07 10:18:44 -0800833TEST_F(DumpstateTest, RunCommandProgressIgnoreThreshold) {
834 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
835 ds.listener_ = listener;
836 ds.listener_name_ = "FoxMulder";
837 SetProgress(0, 8, 5); // 8 max, 5 threshold
838
839 // First update should always be sent.
840 EXPECT_CALL(*listener, onProgressUpdated(1));
Nandana Duttbabf6c72019-01-15 14:11:12 +0000841 EXPECT_CALL(*listener, onProgress(12)); // 1/12 %
Felipe Leme009ecbb2016-11-07 10:18:44 -0800842 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).Build()));
843 std::string progress_message = GetProgressMessage(ds.listener_name_, 1, 8);
844 EXPECT_THAT(out, StrEq("stdout\n"));
845 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
846
847 // Fourth update should be ignored because it's between the threshold (5 -1 = 4 < 5).
848 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(4).Build()));
849 EXPECT_THAT(out, StrEq("stdout\n"));
850 EXPECT_THAT(err, StrEq("stderr\n"));
851
852 // Third update should be sent because it reaches threshold (6 - 1 = 5).
853 EXPECT_CALL(*listener, onProgressUpdated(6));
Nandana Duttbabf6c72019-01-15 14:11:12 +0000854 EXPECT_CALL(*listener, onProgress(75)); // 6/8 %
Felipe Leme009ecbb2016-11-07 10:18:44 -0800855 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).Build()));
856 progress_message = GetProgressMessage(ds.listener_name_, 6, 8);
857 EXPECT_THAT(out, StrEq("stdout\n"));
858 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
859
860 // Fourth update should be ignored because it's between the threshold (9 - 6 = 3 < 5).
861 // But max update should be sent.
862 EXPECT_CALL(*listener, onMaxProgressUpdated(10)); // 9 * 120% = 10.8 = 10
863 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(3).Build()));
864 progress_message = GetProgressMessage(ds.listener_name_, 9, 10, 8, false);
865 EXPECT_THAT(out, StrEq("stdout\n"));
866 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
867
868 ds.listener_.clear();
869}
870
Felipe Lemed80e6b62016-10-03 13:08:14 -0700871TEST_F(DumpstateTest, RunCommandDropRoot) {
Felipe Leme46b85da2016-11-21 17:40:45 -0800872 if (!IsStandalone()) {
873 // TODO: temporarily disabled because it might cause other tests to fail after dropping
874 // to Shell - need to refactor tests to avoid this problem)
875 MYLOGE("Skipping DumpstateTest.RunCommandDropRoot() on test suite\n")
876 return;
877 }
Felipe Lemed80e6b62016-10-03 13:08:14 -0700878 // First check root case - only available when running with 'adb root'.
879 uid_t uid = getuid();
880 if (uid == 0) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700881 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"}));
Felipe Lemed80e6b62016-10-03 13:08:14 -0700882 EXPECT_THAT(out, StrEq("0\nstdout\n"));
883 EXPECT_THAT(err, StrEq("stderr\n"));
884 return;
885 }
Felipe Leme7447d7c2016-11-03 18:12:22 -0700886 // Then run dropping root.
887 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
Felipe Lemed80e6b62016-10-03 13:08:14 -0700888 CommandOptions::WithTimeout(1).DropRoot().Build()));
889 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
Felipe Leme26c41572016-10-06 14:34:43 -0700890 EXPECT_THAT(err, StrEq("drop_root_user(): already running as Shell\nstderr\n"));
Felipe Lemed80e6b62016-10-03 13:08:14 -0700891}
892
893TEST_F(DumpstateTest, RunCommandAsRootUserBuild) {
Felipe Leme46b85da2016-11-21 17:40:45 -0800894 if (!IsStandalone()) {
895 // TODO: temporarily disabled because it might cause other tests to fail after dropping
896 // to Shell - need to refactor tests to avoid this problem)
897 MYLOGE("Skipping DumpstateTest.RunCommandAsRootUserBuild() on test suite\n")
898 return;
899 }
Felipe Lemef0292972016-11-22 13:57:05 -0800900 if (!PropertiesHelper::IsUserBuild()) {
Felipe Lemed80e6b62016-10-03 13:08:14 -0700901 // Emulates user build if necessarily.
902 SetBuildType("user");
903 }
904
905 DropRoot();
906
Felipe Leme7447d7c2016-11-03 18:12:22 -0700907 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).AsRoot().Build()));
Felipe Lemed80e6b62016-10-03 13:08:14 -0700908
909 // We don't know the exact path of su, so we just check for the 'root ...' commands
910 EXPECT_THAT(out, StartsWith("Skipping"));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700911 EXPECT_THAT(out, EndsWith("root " + kSimpleCommand + "' on user build.\n"));
Felipe Lemed80e6b62016-10-03 13:08:14 -0700912 EXPECT_THAT(err, IsEmpty());
913}
914
Felipe Leme46b85da2016-11-21 17:40:45 -0800915TEST_F(DumpstateTest, RunCommandAsRootNonUserBuild) {
916 if (!IsStandalone()) {
917 // TODO: temporarily disabled because it might cause other tests to fail after dropping
918 // to Shell - need to refactor tests to avoid this problem)
919 MYLOGE("Skipping DumpstateTest.RunCommandAsRootNonUserBuild() on test suite\n")
920 return;
921 }
Felipe Lemef0292972016-11-22 13:57:05 -0800922 if (PropertiesHelper::IsUserBuild()) {
Felipe Leme46b85da2016-11-21 17:40:45 -0800923 ALOGI("Skipping RunCommandAsRootNonUserBuild on user builds\n");
924 return;
925 }
926
927 DropRoot();
928
929 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
930 CommandOptions::WithTimeout(1).AsRoot().Build()));
931
932 EXPECT_THAT(out, StrEq("0\nstdout\n"));
933 EXPECT_THAT(err, StrEq("stderr\n"));
934}
935
Nandana Dutt4b392be2018-11-02 16:17:05 +0000936TEST_F(DumpstateTest, RunCommandAsRootNonUserBuild_withUnroot) {
937 if (!IsStandalone()) {
938 // TODO: temporarily disabled because it might cause other tests to fail after dropping
939 // to Shell - need to refactor tests to avoid this problem)
940 MYLOGE(
941 "Skipping DumpstateTest.RunCommandAsRootNonUserBuild_withUnroot() "
942 "on test suite\n")
943 return;
944 }
945 if (PropertiesHelper::IsUserBuild()) {
946 ALOGI("Skipping RunCommandAsRootNonUserBuild_withUnroot on user builds\n");
947 return;
948 }
949
950 // Same test as above, but with unroot property set, which will override su availability.
951 SetUnroot(true);
952 DropRoot();
953
954 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
955 CommandOptions::WithTimeout(1).AsRoot().Build()));
956
957 // AsRoot is ineffective.
958 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
959 EXPECT_THAT(err, StrEq("drop_root_user(): already running as Shell\nstderr\n"));
960}
961
Yifan Hong48e83a12017-10-03 14:10:07 -0700962TEST_F(DumpstateTest, RunCommandAsRootIfAvailableOnUserBuild) {
963 if (!IsStandalone()) {
964 // TODO: temporarily disabled because it might cause other tests to fail after dropping
965 // to Shell - need to refactor tests to avoid this problem)
966 MYLOGE("Skipping DumpstateTest.RunCommandAsRootIfAvailableOnUserBuild() on test suite\n")
967 return;
968 }
969 if (!PropertiesHelper::IsUserBuild()) {
970 // Emulates user build if necessarily.
971 SetBuildType("user");
972 }
973
974 DropRoot();
975
976 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
977 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
978
979 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
980 EXPECT_THAT(err, StrEq("stderr\n"));
981}
982
983TEST_F(DumpstateTest, RunCommandAsRootIfAvailableOnDebugBuild) {
984 if (!IsStandalone()) {
985 // TODO: temporarily disabled because it might cause other tests to fail after dropping
986 // to Shell - need to refactor tests to avoid this problem)
987 MYLOGE("Skipping DumpstateTest.RunCommandAsRootIfAvailableOnDebugBuild() on test suite\n")
988 return;
989 }
990 if (PropertiesHelper::IsUserBuild()) {
991 ALOGI("Skipping RunCommandAsRootNonUserBuild on user builds\n");
992 return;
993 }
994
995 DropRoot();
996
997 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
998 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
999
1000 EXPECT_THAT(out, StrEq("0\nstdout\n"));
1001 EXPECT_THAT(err, StrEq("stderr\n"));
1002}
1003
Nandana Dutt4b392be2018-11-02 16:17:05 +00001004TEST_F(DumpstateTest, RunCommandAsRootIfAvailableOnDebugBuild_withUnroot) {
1005 if (!IsStandalone()) {
1006 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1007 // to Shell - need to refactor tests to avoid this problem)
1008 MYLOGE(
1009 "Skipping DumpstateTest.RunCommandAsRootIfAvailableOnDebugBuild_withUnroot() "
1010 "on test suite\n")
1011 return;
1012 }
1013 if (PropertiesHelper::IsUserBuild()) {
1014 ALOGI("Skipping RunCommandAsRootIfAvailableOnDebugBuild_withUnroot on user builds\n");
1015 return;
1016 }
1017 // Same test as above, but with unroot property set, which will override su availability.
1018 SetUnroot(true);
1019
1020 DropRoot();
1021
1022 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
1023 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
1024
1025 // It's a userdebug build, so "su root" should be available, but unroot=true overrides it.
1026 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
1027 EXPECT_THAT(err, StrEq("stderr\n"));
1028}
1029
Felipe Lemecef02982016-10-03 17:22:22 -07001030TEST_F(DumpstateTest, DumpFileNotFoundNoTitle) {
1031 EXPECT_EQ(-1, DumpFile("", "/I/cant/believe/I/exist"));
1032 EXPECT_THAT(out,
1033 StrEq("*** Error dumping /I/cant/believe/I/exist: No such file or directory\n"));
1034 EXPECT_THAT(err, IsEmpty());
1035}
1036
1037TEST_F(DumpstateTest, DumpFileNotFoundWithTitle) {
1038 EXPECT_EQ(-1, DumpFile("Y U NO EXIST?", "/I/cant/believe/I/exist"));
1039 EXPECT_THAT(err, IsEmpty());
1040 // We don't know the exact duration, so we check the prefix and suffix
1041 EXPECT_THAT(out, StartsWith("*** Error dumping /I/cant/believe/I/exist (Y U NO EXIST?): No "
1042 "such file or directory\n"));
Felipe Lemecef02982016-10-03 17:22:22 -07001043}
1044
1045TEST_F(DumpstateTest, DumpFileSingleLine) {
Felipe Leme7447d7c2016-11-03 18:12:22 -07001046 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -07001047 EXPECT_THAT(err, IsEmpty());
1048 EXPECT_THAT(out, StrEq("I AM LINE1\n")); // dumpstate adds missing newline
1049}
1050
1051TEST_F(DumpstateTest, DumpFileSingleLineWithNewLine) {
Felipe Leme7447d7c2016-11-03 18:12:22 -07001052 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line-with-newline.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -07001053 EXPECT_THAT(err, IsEmpty());
1054 EXPECT_THAT(out, StrEq("I AM LINE1\n"));
1055}
1056
1057TEST_F(DumpstateTest, DumpFileMultipleLines) {
Felipe Leme7447d7c2016-11-03 18:12:22 -07001058 EXPECT_EQ(0, DumpFile("", kTestDataPath + "multiple-lines.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -07001059 EXPECT_THAT(err, IsEmpty());
1060 EXPECT_THAT(out, StrEq("I AM LINE1\nI AM LINE2\nI AM LINE3\n"));
1061}
1062
1063TEST_F(DumpstateTest, DumpFileMultipleLinesWithNewLine) {
Felipe Leme7447d7c2016-11-03 18:12:22 -07001064 EXPECT_EQ(0, DumpFile("", kTestDataPath + "multiple-lines-with-newline.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -07001065 EXPECT_THAT(err, IsEmpty());
1066 EXPECT_THAT(out, StrEq("I AM LINE1\nI AM LINE2\nI AM LINE3\n"));
1067}
1068
1069TEST_F(DumpstateTest, DumpFileOnDryRunNoTitle) {
1070 SetDryRun(true);
Felipe Leme7447d7c2016-11-03 18:12:22 -07001071 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -07001072 EXPECT_THAT(err, IsEmpty());
1073 EXPECT_THAT(out, IsEmpty());
1074}
1075
1076TEST_F(DumpstateTest, DumpFileOnDryRun) {
1077 SetDryRun(true);
Felipe Leme7447d7c2016-11-03 18:12:22 -07001078 EXPECT_EQ(0, DumpFile("Might as well dump. Dump!", kTestDataPath + "single-line.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -07001079 EXPECT_THAT(err, IsEmpty());
Felipe Leme46b85da2016-11-21 17:40:45 -08001080 EXPECT_THAT(
1081 out, StartsWith("------ Might as well dump. Dump! (" + kTestDataPath + "single-line.txt:"));
Nandana Dutt47527b52019-03-29 15:34:36 +00001082 EXPECT_THAT(out, HasSubstr("\n\t(skipped on dry run)\n"));
Felipe Lemecef02982016-10-03 17:22:22 -07001083}
1084
Felipe Leme75876a22016-10-27 16:31:27 -07001085TEST_F(DumpstateTest, DumpFileUpdateProgress) {
1086 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
1087 ds.listener_ = listener;
1088 ds.listener_name_ = "FoxMulder";
Felipe Leme7447d7c2016-11-03 18:12:22 -07001089 SetProgress(0, 30);
Felipe Leme75876a22016-10-27 16:31:27 -07001090
1091 EXPECT_CALL(*listener, onProgressUpdated(5));
Nandana Duttbabf6c72019-01-15 14:11:12 +00001092 EXPECT_CALL(*listener, onProgress(16)); // 5/30 %
Felipe Leme7447d7c2016-11-03 18:12:22 -07001093 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
Felipe Leme75876a22016-10-27 16:31:27 -07001094
1095 std::string progress_message =
1096 GetProgressMessage(ds.listener_name_, 5, 30); // TODO: unhardcode WEIGHT_FILE (5)?
1097 EXPECT_THAT(err, StrEq(progress_message));
1098 EXPECT_THAT(out, StrEq("I AM LINE1\n")); // dumpstate adds missing newline
1099
1100 ds.listener_.clear();
1101}
1102
Felipe Leme7447d7c2016-11-03 18:12:22 -07001103class DumpstateServiceTest : public DumpstateBaseTest {
Felipe Leme75876a22016-10-27 16:31:27 -07001104 public:
1105 DumpstateService dss;
1106};
1107
1108TEST_F(DumpstateServiceTest, SetListenerNoName) {
1109 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
Felipe Leme009ecbb2016-11-07 10:18:44 -08001110 sp<IDumpstateToken> token;
Vishnu Nair20cf5032018-01-05 13:15:49 -08001111 EXPECT_TRUE(dss.setListener("", listener, /* getSectionDetails = */ false, &token).isOk());
Felipe Leme009ecbb2016-11-07 10:18:44 -08001112 ASSERT_THAT(token, IsNull());
Felipe Leme75876a22016-10-27 16:31:27 -07001113}
1114
1115TEST_F(DumpstateServiceTest, SetListenerNoPointer) {
Felipe Leme009ecbb2016-11-07 10:18:44 -08001116 sp<IDumpstateToken> token;
Vishnu Nair20cf5032018-01-05 13:15:49 -08001117 EXPECT_TRUE(
1118 dss.setListener("whatever", nullptr, /* getSectionDetails = */ false, &token).isOk());
Felipe Leme009ecbb2016-11-07 10:18:44 -08001119 ASSERT_THAT(token, IsNull());
Felipe Leme75876a22016-10-27 16:31:27 -07001120}
1121
1122TEST_F(DumpstateServiceTest, SetListenerTwice) {
1123 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
Felipe Leme009ecbb2016-11-07 10:18:44 -08001124 sp<IDumpstateToken> token;
Vishnu Nair20cf5032018-01-05 13:15:49 -08001125 EXPECT_TRUE(
1126 dss.setListener("whatever", listener, /* getSectionDetails = */ false, &token).isOk());
Felipe Leme009ecbb2016-11-07 10:18:44 -08001127 ASSERT_THAT(token, NotNull());
Felipe Leme75876a22016-10-27 16:31:27 -07001128 EXPECT_THAT(Dumpstate::GetInstance().listener_name_, StrEq("whatever"));
Vishnu Nair20cf5032018-01-05 13:15:49 -08001129 EXPECT_FALSE(Dumpstate::GetInstance().report_section_);
Felipe Leme75876a22016-10-27 16:31:27 -07001130
Felipe Leme009ecbb2016-11-07 10:18:44 -08001131 token.clear();
Vishnu Nair20cf5032018-01-05 13:15:49 -08001132 EXPECT_TRUE(
1133 dss.setListener("whatsoever", listener, /* getSectionDetails = */ false, &token).isOk());
Felipe Leme009ecbb2016-11-07 10:18:44 -08001134 ASSERT_THAT(token, IsNull());
1135 EXPECT_THAT(Dumpstate::GetInstance().listener_name_, StrEq("whatever"));
Vishnu Nair20cf5032018-01-05 13:15:49 -08001136 EXPECT_FALSE(Dumpstate::GetInstance().report_section_);
1137}
1138
1139TEST_F(DumpstateServiceTest, SetListenerWithSectionDetails) {
1140 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
1141 sp<IDumpstateToken> token;
1142 Dumpstate::GetInstance().listener_ = nullptr;
1143 EXPECT_TRUE(
1144 dss.setListener("whatever", listener, /* getSectionDetails = */ true, &token).isOk());
1145 ASSERT_THAT(token, NotNull());
1146 EXPECT_THAT(Dumpstate::GetInstance().listener_name_, StrEq("whatever"));
1147 EXPECT_TRUE(Dumpstate::GetInstance().report_section_);
Felipe Leme75876a22016-10-27 16:31:27 -07001148}
Felipe Leme7447d7c2016-11-03 18:12:22 -07001149
1150class ProgressTest : public DumpstateBaseTest {
1151 public:
1152 Progress GetInstance(int32_t max, double growth_factor, const std::string& path = "") {
1153 return Progress(max, growth_factor, path);
1154 }
1155
1156 void AssertStats(const std::string& path, int32_t expected_runs, int32_t expected_average) {
1157 std::string expected_content =
1158 android::base::StringPrintf("%d %d\n", expected_runs, expected_average);
1159 std::string actual_content;
Felipe Leme46b85da2016-11-21 17:40:45 -08001160 ReadFileToString(path, &actual_content);
Felipe Leme7447d7c2016-11-03 18:12:22 -07001161 ASSERT_THAT(actual_content, StrEq(expected_content)) << "invalid stats on " << path;
1162 }
1163};
1164
1165TEST_F(ProgressTest, SimpleTest) {
1166 Progress progress;
1167 EXPECT_EQ(0, progress.Get());
1168 EXPECT_EQ(Progress::kDefaultMax, progress.GetInitialMax());
1169 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1170
1171 bool max_increased = progress.Inc(1);
1172 EXPECT_EQ(1, progress.Get());
1173 EXPECT_EQ(Progress::kDefaultMax, progress.GetInitialMax());
1174 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1175 EXPECT_FALSE(max_increased);
1176
1177 // Ignore negative increase.
1178 max_increased = progress.Inc(-1);
1179 EXPECT_EQ(1, progress.Get());
1180 EXPECT_EQ(Progress::kDefaultMax, progress.GetInitialMax());
1181 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1182 EXPECT_FALSE(max_increased);
1183}
1184
1185TEST_F(ProgressTest, MaxGrowsInsideNewRange) {
1186 Progress progress = GetInstance(10, 1.2); // 20% growth factor
1187 EXPECT_EQ(0, progress.Get());
1188 EXPECT_EQ(10, progress.GetInitialMax());
1189 EXPECT_EQ(10, progress.GetMax());
1190
1191 // No increase
1192 bool max_increased = progress.Inc(10);
1193 EXPECT_EQ(10, progress.Get());
1194 EXPECT_EQ(10, progress.GetMax());
1195 EXPECT_FALSE(max_increased);
1196
1197 // Increase, with new value < max*20%
1198 max_increased = progress.Inc(1);
1199 EXPECT_EQ(11, progress.Get());
1200 EXPECT_EQ(13, progress.GetMax()); // 11 average * 20% growth = 13.2 = 13
1201 EXPECT_TRUE(max_increased);
1202}
1203
1204TEST_F(ProgressTest, MaxGrowsOutsideNewRange) {
1205 Progress progress = GetInstance(10, 1.2); // 20% growth factor
1206 EXPECT_EQ(0, progress.Get());
1207 EXPECT_EQ(10, progress.GetInitialMax());
1208 EXPECT_EQ(10, progress.GetMax());
1209
1210 // No increase
1211 bool max_increased = progress.Inc(10);
1212 EXPECT_EQ(10, progress.Get());
1213 EXPECT_EQ(10, progress.GetMax());
1214 EXPECT_FALSE(max_increased);
1215
1216 // Increase, with new value > max*20%
1217 max_increased = progress.Inc(5);
1218 EXPECT_EQ(15, progress.Get());
1219 EXPECT_EQ(18, progress.GetMax()); // 15 average * 20% growth = 18
1220 EXPECT_TRUE(max_increased);
1221}
1222
1223TEST_F(ProgressTest, InvalidPath) {
1224 Progress progress("/devil/null");
1225 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1226}
1227
1228TEST_F(ProgressTest, EmptyFile) {
1229 Progress progress(CopyTextFileFixture("empty-file.txt"));
1230 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1231}
1232
1233TEST_F(ProgressTest, InvalidLine1stEntryNAN) {
1234 Progress progress(CopyTextFileFixture("stats-invalid-1st-NAN.txt"));
1235 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1236}
1237
1238TEST_F(ProgressTest, InvalidLine2ndEntryNAN) {
1239 Progress progress(CopyTextFileFixture("stats-invalid-2nd-NAN.txt"));
1240 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1241}
1242
1243TEST_F(ProgressTest, InvalidLineBothNAN) {
1244 Progress progress(CopyTextFileFixture("stats-invalid-both-NAN.txt"));
1245 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1246}
1247
1248TEST_F(ProgressTest, InvalidLine1stEntryNegative) {
1249 Progress progress(CopyTextFileFixture("stats-invalid-1st-negative.txt"));
1250 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1251}
1252
1253TEST_F(ProgressTest, InvalidLine2ndEntryNegative) {
1254 Progress progress(CopyTextFileFixture("stats-invalid-2nd-negative.txt"));
1255 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1256}
1257
1258TEST_F(ProgressTest, InvalidLine1stEntryTooBig) {
1259 Progress progress(CopyTextFileFixture("stats-invalid-1st-too-big.txt"));
1260 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1261}
1262
1263TEST_F(ProgressTest, InvalidLine2ndEntryTooBig) {
1264 Progress progress(CopyTextFileFixture("stats-invalid-2nd-too-big.txt"));
1265 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1266}
1267
1268// Tests stats are properly saved when the file does not exists.
1269TEST_F(ProgressTest, FirstTime) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001270 if (!IsStandalone()) {
1271 // TODO: temporarily disabled because it's failing when running as suite
1272 MYLOGE("Skipping ProgressTest.FirstTime() on test suite\n")
1273 return;
1274 }
1275
Felipe Leme7447d7c2016-11-03 18:12:22 -07001276 std::string path = kTestDataPath + "FirstTime.txt";
1277 android::base::RemoveFileIfExists(path);
1278
1279 Progress run1(path);
1280 EXPECT_EQ(0, run1.Get());
1281 EXPECT_EQ(Progress::kDefaultMax, run1.GetInitialMax());
1282 EXPECT_EQ(Progress::kDefaultMax, run1.GetMax());
1283
1284 bool max_increased = run1.Inc(20);
1285 EXPECT_EQ(20, run1.Get());
1286 EXPECT_EQ(Progress::kDefaultMax, run1.GetMax());
1287 EXPECT_FALSE(max_increased);
1288
1289 run1.Save();
1290 AssertStats(path, 1, 20);
1291}
1292
1293// Tests what happens when the persistent settings contains the average duration of 1 run.
1294// Data on file is 1 run and 109 average.
1295TEST_F(ProgressTest, SecondTime) {
1296 std::string path = CopyTextFileFixture("stats-one-run-no-newline.txt");
1297
1298 Progress run1 = GetInstance(-42, 1.2, path);
1299 EXPECT_EQ(0, run1.Get());
1300 EXPECT_EQ(10, run1.GetInitialMax());
1301 EXPECT_EQ(10, run1.GetMax());
1302
1303 bool max_increased = run1.Inc(20);
1304 EXPECT_EQ(20, run1.Get());
1305 EXPECT_EQ(24, run1.GetMax());
1306 EXPECT_TRUE(max_increased);
1307
1308 // Average now is 2 runs and (10 + 20)/ 2 = 15
1309 run1.Save();
1310 AssertStats(path, 2, 15);
1311
1312 Progress run2 = GetInstance(-42, 1.2, path);
1313 EXPECT_EQ(0, run2.Get());
1314 EXPECT_EQ(15, run2.GetInitialMax());
1315 EXPECT_EQ(15, run2.GetMax());
1316
1317 max_increased = run2.Inc(25);
1318 EXPECT_EQ(25, run2.Get());
1319 EXPECT_EQ(30, run2.GetMax());
1320 EXPECT_TRUE(max_increased);
1321
1322 // Average now is 3 runs and (15 * 2 + 25)/ 3 = 18.33 = 18
1323 run2.Save();
1324 AssertStats(path, 3, 18);
1325
1326 Progress run3 = GetInstance(-42, 1.2, path);
1327 EXPECT_EQ(0, run3.Get());
1328 EXPECT_EQ(18, run3.GetInitialMax());
1329 EXPECT_EQ(18, run3.GetMax());
1330
1331 // Make sure average decreases as well
1332 max_increased = run3.Inc(5);
1333 EXPECT_EQ(5, run3.Get());
1334 EXPECT_EQ(18, run3.GetMax());
1335 EXPECT_FALSE(max_increased);
1336
1337 // Average now is 4 runs and (18 * 3 + 5)/ 4 = 14.75 = 14
1338 run3.Save();
1339 AssertStats(path, 4, 14);
1340}
1341
1342// Tests what happens when the persistent settings contains the average duration of 2 runs.
1343// Data on file is 2 runs and 15 average.
1344TEST_F(ProgressTest, ThirdTime) {
1345 std::string path = CopyTextFileFixture("stats-two-runs.txt");
1346 AssertStats(path, 2, 15); // Sanity check
1347
1348 Progress run1 = GetInstance(-42, 1.2, path);
1349 EXPECT_EQ(0, run1.Get());
1350 EXPECT_EQ(15, run1.GetInitialMax());
1351 EXPECT_EQ(15, run1.GetMax());
1352
1353 bool max_increased = run1.Inc(20);
1354 EXPECT_EQ(20, run1.Get());
1355 EXPECT_EQ(24, run1.GetMax());
1356 EXPECT_TRUE(max_increased);
1357
1358 // Average now is 3 runs and (15 * 2 + 20)/ 3 = 16.66 = 16
1359 run1.Save();
1360 AssertStats(path, 3, 16);
1361}
1362
Felipe Leme46b85da2016-11-21 17:40:45 -08001363class DumpstateUtilTest : public DumpstateBaseTest {
1364 public:
1365 void SetUp() {
1366 DumpstateBaseTest::SetUp();
1367 SetDryRun(false);
1368 }
1369
Felipe Leme46b85da2016-11-21 17:40:45 -08001370 void CaptureFdOut() {
Felipe Lemef0292972016-11-22 13:57:05 -08001371 ReadFileToString(path_, &out);
Felipe Leme46b85da2016-11-21 17:40:45 -08001372 }
1373
1374 void CreateFd(const std::string& name) {
1375 path_ = kTestDataPath + name;
1376 MYLOGD("Creating fd for file %s\n", path_.c_str());
1377
1378 fd = TEMP_FAILURE_RETRY(open(path_.c_str(),
1379 O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW,
1380 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH));
1381 ASSERT_GE(fd, 0) << "could not create FD for path " << path_;
1382 }
1383
1384 // Runs a command into the `fd` and capture `stderr`.
Felipe Lemef0292972016-11-22 13:57:05 -08001385 int RunCommand(const std::string& title, const std::vector<std::string>& full_command,
Felipe Leme46b85da2016-11-21 17:40:45 -08001386 const CommandOptions& options = CommandOptions::DEFAULT) {
1387 CaptureStderr();
Felipe Lemef0292972016-11-22 13:57:05 -08001388 int status = RunCommandToFd(fd, title, full_command, options);
Felipe Leme46b85da2016-11-21 17:40:45 -08001389 close(fd);
1390
1391 CaptureFdOut();
1392 err = GetCapturedStderr();
1393 return status;
1394 }
1395
1396 // Dumps a file and into the `fd` and `stderr`.
Felipe Lemef0292972016-11-22 13:57:05 -08001397 int DumpFile(const std::string& title, const std::string& path) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001398 CaptureStderr();
Felipe Lemef0292972016-11-22 13:57:05 -08001399 int status = DumpFileToFd(fd, title, path);
Felipe Leme46b85da2016-11-21 17:40:45 -08001400 close(fd);
1401
1402 CaptureFdOut();
1403 err = GetCapturedStderr();
1404 return status;
1405 }
1406
Ecco Park61ffcf72016-10-27 15:46:26 -07001407 // Find out the pid of the process_name
1408 int FindPidOfProcess(const std::string& process_name) {
1409 CaptureStderr();
1410 int status = GetPidByName(process_name);
1411 err = GetCapturedStderr();
1412 return status;
1413 }
1414
Felipe Leme46b85da2016-11-21 17:40:45 -08001415 int fd;
1416
1417 // 'fd` output and `stderr` from the last command ran.
1418 std::string out, err;
1419
1420 private:
1421 std::string path_;
1422};
1423
1424TEST_F(DumpstateUtilTest, RunCommandNoArgs) {
Felipe Lemef0292972016-11-22 13:57:05 -08001425 CreateFd("RunCommandNoArgs.txt");
1426 EXPECT_EQ(-1, RunCommand("", {}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001427}
1428
Felipe Lemef0292972016-11-22 13:57:05 -08001429TEST_F(DumpstateUtilTest, RunCommandNoTitle) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001430 CreateFd("RunCommandWithNoArgs.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001431 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001432 EXPECT_THAT(out, StrEq("stdout\n"));
1433 EXPECT_THAT(err, StrEq("stderr\n"));
1434}
1435
Felipe Lemef0292972016-11-22 13:57:05 -08001436TEST_F(DumpstateUtilTest, RunCommandWithTitle) {
1437 CreateFd("RunCommandWithNoArgs.txt");
1438 EXPECT_EQ(0, RunCommand("I AM GROOT", {kSimpleCommand}));
1439 EXPECT_THAT(out, StrEq("------ I AM GROOT (" + kSimpleCommand + ") ------\nstdout\n"));
1440 EXPECT_THAT(err, StrEq("stderr\n"));
1441}
1442
Felipe Leme46b85da2016-11-21 17:40:45 -08001443TEST_F(DumpstateUtilTest, RunCommandWithOneArg) {
1444 CreateFd("RunCommandWithOneArg.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001445 EXPECT_EQ(0, RunCommand("", {kEchoCommand, "one"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001446 EXPECT_THAT(err, IsEmpty());
1447 EXPECT_THAT(out, StrEq("one\n"));
1448}
1449
1450TEST_F(DumpstateUtilTest, RunCommandWithMultipleArgs) {
1451 CreateFd("RunCommandWithMultipleArgs.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001452 EXPECT_EQ(0, RunCommand("", {kEchoCommand, "one", "is", "the", "loniest", "number"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001453 EXPECT_THAT(err, IsEmpty());
1454 EXPECT_THAT(out, StrEq("one is the loniest number\n"));
1455}
1456
1457TEST_F(DumpstateUtilTest, RunCommandWithLoggingMessage) {
1458 CreateFd("RunCommandWithLoggingMessage.txt");
1459 EXPECT_EQ(
Felipe Lemef0292972016-11-22 13:57:05 -08001460 0, RunCommand("", {kSimpleCommand},
Felipe Leme46b85da2016-11-21 17:40:45 -08001461 CommandOptions::WithTimeout(10).Log("COMMAND, Y U NO LOG FIRST?").Build()));
1462 EXPECT_THAT(out, StrEq("stdout\n"));
1463 EXPECT_THAT(err, StrEq("COMMAND, Y U NO LOG FIRST?stderr\n"));
1464}
1465
1466TEST_F(DumpstateUtilTest, RunCommandRedirectStderr) {
1467 CreateFd("RunCommandRedirectStderr.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001468 EXPECT_EQ(0, RunCommand("", {kSimpleCommand},
1469 CommandOptions::WithTimeout(10).RedirectStderr().Build()));
Felipe Leme46b85da2016-11-21 17:40:45 -08001470 EXPECT_THAT(out, IsEmpty());
1471 EXPECT_THAT(err, StrEq("stdout\nstderr\n"));
1472}
1473
1474TEST_F(DumpstateUtilTest, RunCommandDryRun) {
1475 CreateFd("RunCommandDryRun.txt");
1476 SetDryRun(true);
Felipe Lemef0292972016-11-22 13:57:05 -08001477 EXPECT_EQ(0, RunCommand("I AM GROOT", {kSimpleCommand}));
1478 EXPECT_THAT(out, StrEq(android::base::StringPrintf(
1479 "------ I AM GROOT (%s) ------\n\t(skipped on dry run)\n",
1480 kSimpleCommand.c_str())));
1481 EXPECT_THAT(err, IsEmpty());
1482}
1483
1484TEST_F(DumpstateUtilTest, RunCommandDryRunNoTitle) {
1485 CreateFd("RunCommandDryRun.txt");
1486 SetDryRun(true);
1487 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001488 EXPECT_THAT(
1489 out, StrEq(android::base::StringPrintf("%s: skipped on dry run\n", kSimpleCommand.c_str())));
1490 EXPECT_THAT(err, IsEmpty());
1491}
1492
1493TEST_F(DumpstateUtilTest, RunCommandDryRunAlways) {
1494 CreateFd("RunCommandDryRunAlways.txt");
1495 SetDryRun(true);
Felipe Lemef0292972016-11-22 13:57:05 -08001496 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(10).Always().Build()));
Felipe Leme46b85da2016-11-21 17:40:45 -08001497 EXPECT_THAT(out, StrEq("stdout\n"));
1498 EXPECT_THAT(err, StrEq("stderr\n"));
1499}
1500
1501TEST_F(DumpstateUtilTest, RunCommandNotFound) {
1502 CreateFd("RunCommandNotFound.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001503 EXPECT_NE(0, RunCommand("", {"/there/cannot/be/such/command"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001504 EXPECT_THAT(out, StartsWith("*** command '/there/cannot/be/such/command' failed: exit code"));
1505 EXPECT_THAT(err, StartsWith("execvp on command '/there/cannot/be/such/command' failed"));
1506}
1507
1508TEST_F(DumpstateUtilTest, RunCommandFails) {
1509 CreateFd("RunCommandFails.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001510 EXPECT_EQ(42, RunCommand("", {kSimpleCommand, "--exit", "42"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001511 EXPECT_THAT(out, StrEq("stdout\n*** command '" + kSimpleCommand +
1512 " --exit 42' failed: exit code 42\n"));
1513 EXPECT_THAT(err, StrEq("stderr\n*** command '" + kSimpleCommand +
1514 " --exit 42' failed: exit code 42\n"));
1515}
1516
1517TEST_F(DumpstateUtilTest, RunCommandCrashes) {
1518 CreateFd("RunCommandCrashes.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001519 EXPECT_NE(0, RunCommand("", {kSimpleCommand, "--crash"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001520 // We don't know the exit code, so check just the prefix.
1521 EXPECT_THAT(
1522 out, StartsWith("stdout\n*** command '" + kSimpleCommand + " --crash' failed: exit code"));
1523 EXPECT_THAT(
1524 err, StartsWith("stderr\n*** command '" + kSimpleCommand + " --crash' failed: exit code"));
1525}
1526
Vishnu Nair6921f802017-11-22 09:17:23 -08001527TEST_F(DumpstateUtilTest, RunCommandTimesoutWithSec) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001528 CreateFd("RunCommandTimesout.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001529 EXPECT_EQ(-1, RunCommand("", {kSimpleCommand, "--sleep", "2"},
1530 CommandOptions::WithTimeout(1).Build()));
Felipe Leme46b85da2016-11-21 17:40:45 -08001531 EXPECT_THAT(out, StartsWith("stdout line1\n*** command '" + kSimpleCommand +
1532 " --sleep 2' timed out after 1"));
1533 EXPECT_THAT(err, StartsWith("sleeping for 2s\n*** command '" + kSimpleCommand +
1534 " --sleep 2' timed out after 1"));
1535}
1536
Vishnu Nair6921f802017-11-22 09:17:23 -08001537TEST_F(DumpstateUtilTest, RunCommandTimesoutWithMsec) {
1538 CreateFd("RunCommandTimesout.txt");
1539 EXPECT_EQ(-1, RunCommand("", {kSimpleCommand, "--sleep", "2"},
1540 CommandOptions::WithTimeoutInMs(1000).Build()));
1541 EXPECT_THAT(out, StartsWith("stdout line1\n*** command '" + kSimpleCommand +
1542 " --sleep 2' timed out after 1"));
1543 EXPECT_THAT(err, StartsWith("sleeping for 2s\n*** command '" + kSimpleCommand +
1544 " --sleep 2' timed out after 1"));
1545}
1546
1547
Felipe Leme46b85da2016-11-21 17:40:45 -08001548TEST_F(DumpstateUtilTest, RunCommandIsKilled) {
1549 CreateFd("RunCommandIsKilled.txt");
1550 CaptureStderr();
1551
1552 std::thread t([=]() {
Felipe Lemef0292972016-11-22 13:57:05 -08001553 EXPECT_EQ(SIGTERM, RunCommandToFd(fd, "", {kSimpleCommand, "--pid", "--sleep", "20"},
Felipe Leme46b85da2016-11-21 17:40:45 -08001554 CommandOptions::WithTimeout(100).Always().Build()));
1555 });
1556
1557 // Capture pid and pre-sleep output.
1558 sleep(1); // Wait a little bit to make sure pid and 1st line were printed.
1559 std::string err = GetCapturedStderr();
1560 EXPECT_THAT(err, StrEq("sleeping for 20s\n"));
1561
1562 CaptureFdOut();
1563 std::vector<std::string> lines = android::base::Split(out, "\n");
1564 ASSERT_EQ(3, (int)lines.size()) << "Invalid lines before sleep: " << out;
1565
1566 int pid = atoi(lines[0].c_str());
1567 EXPECT_THAT(lines[1], StrEq("stdout line1"));
1568 EXPECT_THAT(lines[2], IsEmpty()); // \n
1569
1570 // Then kill the process.
1571 CaptureFdOut();
1572 CaptureStderr();
1573 ASSERT_EQ(0, kill(pid, SIGTERM)) << "failed to kill pid " << pid;
1574 t.join();
1575
1576 // Finally, check output after murder.
1577 CaptureFdOut();
1578 err = GetCapturedStderr();
1579
1580 // out starts with the pid, which is an unknown
1581 EXPECT_THAT(out, EndsWith("stdout line1\n*** command '" + kSimpleCommand +
1582 " --pid --sleep 20' failed: killed by signal 15\n"));
1583 EXPECT_THAT(err, StrEq("*** command '" + kSimpleCommand +
1584 " --pid --sleep 20' failed: killed by signal 15\n"));
1585}
1586
1587TEST_F(DumpstateUtilTest, RunCommandAsRootUserBuild) {
1588 if (!IsStandalone()) {
1589 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1590 // to Shell - need to refactor tests to avoid this problem)
1591 MYLOGE("Skipping DumpstateUtilTest.RunCommandAsRootUserBuild() on test suite\n")
1592 return;
1593 }
1594 CreateFd("RunCommandAsRootUserBuild.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001595 if (!PropertiesHelper::IsUserBuild()) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001596 // Emulates user build if necessarily.
1597 SetBuildType("user");
1598 }
1599
1600 DropRoot();
1601
Felipe Lemef0292972016-11-22 13:57:05 -08001602 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).AsRoot().Build()));
Felipe Leme46b85da2016-11-21 17:40:45 -08001603
1604 // We don't know the exact path of su, so we just check for the 'root ...' commands
1605 EXPECT_THAT(out, StartsWith("Skipping"));
1606 EXPECT_THAT(out, EndsWith("root " + kSimpleCommand + "' on user build.\n"));
1607 EXPECT_THAT(err, IsEmpty());
1608}
1609
1610TEST_F(DumpstateUtilTest, RunCommandAsRootNonUserBuild) {
1611 if (!IsStandalone()) {
1612 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1613 // to Shell - need to refactor tests to avoid this problem)
1614 MYLOGE("Skipping DumpstateUtilTest.RunCommandAsRootNonUserBuild() on test suite\n")
1615 return;
1616 }
1617 CreateFd("RunCommandAsRootNonUserBuild.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001618 if (PropertiesHelper::IsUserBuild()) {
Felipe Leme7447d7c2016-11-03 18:12:22 -07001619 ALOGI("Skipping RunCommandAsRootNonUserBuild on user builds\n");
1620 return;
1621 }
1622
1623 DropRoot();
1624
Felipe Lemef0292972016-11-22 13:57:05 -08001625 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
1626 CommandOptions::WithTimeout(1).AsRoot().Build()));
Felipe Leme7447d7c2016-11-03 18:12:22 -07001627
1628 EXPECT_THAT(out, StrEq("0\nstdout\n"));
1629 EXPECT_THAT(err, StrEq("stderr\n"));
1630}
Felipe Leme46b85da2016-11-21 17:40:45 -08001631
Yifan Hong48e83a12017-10-03 14:10:07 -07001632
1633TEST_F(DumpstateUtilTest, RunCommandAsRootIfAvailableOnUserBuild) {
1634 if (!IsStandalone()) {
1635 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1636 // to Shell - need to refactor tests to avoid this problem)
1637 MYLOGE("Skipping DumpstateUtilTest.RunCommandAsRootIfAvailableOnUserBuild() on test suite\n")
1638 return;
1639 }
1640 CreateFd("RunCommandAsRootIfAvailableOnUserBuild.txt");
1641 if (!PropertiesHelper::IsUserBuild()) {
1642 // Emulates user build if necessarily.
1643 SetBuildType("user");
1644 }
1645
1646 DropRoot();
1647
1648 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
1649 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
1650
1651 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
1652 EXPECT_THAT(err, StrEq("stderr\n"));
1653}
1654
1655TEST_F(DumpstateUtilTest, RunCommandAsRootIfAvailableOnDebugBuild) {
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.RunCommandAsRootIfAvailableOnDebugBuild() on test suite\n")
1660 return;
1661 }
1662 CreateFd("RunCommandAsRootIfAvailableOnDebugBuild.txt");
1663 if (PropertiesHelper::IsUserBuild()) {
1664 ALOGI("Skipping RunCommandAsRootNonUserBuild on user builds\n");
1665 return;
1666 }
1667
1668 DropRoot();
1669
1670 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
1671 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
1672
1673 EXPECT_THAT(out, StrEq("0\nstdout\n"));
1674 EXPECT_THAT(err, StrEq("stderr\n"));
1675}
1676
Felipe Leme46b85da2016-11-21 17:40:45 -08001677TEST_F(DumpstateUtilTest, RunCommandDropRoot) {
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.RunCommandDropRoot() on test suite\n")
1682 return;
1683 }
1684 CreateFd("RunCommandDropRoot.txt");
1685 // First check root case - only available when running with 'adb root'.
1686 uid_t uid = getuid();
1687 if (uid == 0) {
Felipe Lemef0292972016-11-22 13:57:05 -08001688 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001689 EXPECT_THAT(out, StrEq("0\nstdout\n"));
1690 EXPECT_THAT(err, StrEq("stderr\n"));
1691 return;
1692 }
1693 // Then run dropping root.
Felipe Lemef0292972016-11-22 13:57:05 -08001694 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
Felipe Leme46b85da2016-11-21 17:40:45 -08001695 CommandOptions::WithTimeout(1).DropRoot().Build()));
1696 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
1697 EXPECT_THAT(err, StrEq("drop_root_user(): already running as Shell\nstderr\n"));
1698}
1699
Felipe Lemef0292972016-11-22 13:57:05 -08001700TEST_F(DumpstateUtilTest, DumpFileNotFoundNoTitle) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001701 CreateFd("DumpFileNotFound.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001702 EXPECT_EQ(-1, DumpFile("", "/I/cant/believe/I/exist"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001703 EXPECT_THAT(out,
1704 StrEq("*** Error dumping /I/cant/believe/I/exist: No such file or directory\n"));
1705 EXPECT_THAT(err, IsEmpty());
1706}
1707
Felipe Lemef0292972016-11-22 13:57:05 -08001708TEST_F(DumpstateUtilTest, DumpFileNotFoundWithTitle) {
1709 CreateFd("DumpFileNotFound.txt");
1710 EXPECT_EQ(-1, DumpFile("Y U NO EXIST?", "/I/cant/believe/I/exist"));
1711 EXPECT_THAT(out, StrEq("*** Error dumping /I/cant/believe/I/exist (Y U NO EXIST?): No such "
1712 "file or directory\n"));
1713 EXPECT_THAT(err, IsEmpty());
1714}
1715
Felipe Leme46b85da2016-11-21 17:40:45 -08001716TEST_F(DumpstateUtilTest, DumpFileSingleLine) {
1717 CreateFd("DumpFileSingleLine.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001718 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001719 EXPECT_THAT(err, IsEmpty());
1720 EXPECT_THAT(out, StrEq("I AM LINE1\n")); // dumpstate adds missing newline
1721}
1722
1723TEST_F(DumpstateUtilTest, DumpFileSingleLineWithNewLine) {
1724 CreateFd("DumpFileSingleLineWithNewLine.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001725 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line-with-newline.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001726 EXPECT_THAT(err, IsEmpty());
1727 EXPECT_THAT(out, StrEq("I AM LINE1\n"));
1728}
1729
1730TEST_F(DumpstateUtilTest, DumpFileMultipleLines) {
1731 CreateFd("DumpFileMultipleLines.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001732 EXPECT_EQ(0, DumpFile("", kTestDataPath + "multiple-lines.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001733 EXPECT_THAT(err, IsEmpty());
1734 EXPECT_THAT(out, StrEq("I AM LINE1\nI AM LINE2\nI AM LINE3\n"));
1735}
1736
1737TEST_F(DumpstateUtilTest, DumpFileMultipleLinesWithNewLine) {
1738 CreateFd("DumpFileMultipleLinesWithNewLine.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001739 EXPECT_EQ(0, DumpFile("", kTestDataPath + "multiple-lines-with-newline.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001740 EXPECT_THAT(err, IsEmpty());
1741 EXPECT_THAT(out, StrEq("I AM LINE1\nI AM LINE2\nI AM LINE3\n"));
1742}
1743
Felipe Lemef0292972016-11-22 13:57:05 -08001744TEST_F(DumpstateUtilTest, DumpFileOnDryRunNoTitle) {
1745 CreateFd("DumpFileOnDryRun.txt");
1746 SetDryRun(true);
1747 std::string path = kTestDataPath + "single-line.txt";
1748 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
1749 EXPECT_THAT(err, IsEmpty());
1750 EXPECT_THAT(out, StrEq(path + ": skipped on dry run\n"));
1751}
1752
Felipe Leme46b85da2016-11-21 17:40:45 -08001753TEST_F(DumpstateUtilTest, DumpFileOnDryRun) {
1754 CreateFd("DumpFileOnDryRun.txt");
1755 SetDryRun(true);
1756 std::string path = kTestDataPath + "single-line.txt";
Felipe Lemef0292972016-11-22 13:57:05 -08001757 EXPECT_EQ(0, DumpFile("Might as well dump. Dump!", kTestDataPath + "single-line.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001758 EXPECT_THAT(err, IsEmpty());
Felipe Lemef0292972016-11-22 13:57:05 -08001759 EXPECT_THAT(
1760 out, StartsWith("------ Might as well dump. Dump! (" + kTestDataPath + "single-line.txt:"));
1761 EXPECT_THAT(out, EndsWith("skipped on dry run\n"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001762}
Ecco Park61ffcf72016-10-27 15:46:26 -07001763
1764TEST_F(DumpstateUtilTest, FindingPidWithExistingProcess) {
1765 // init process always has pid 1.
1766 EXPECT_EQ(1, FindPidOfProcess("init"));
1767 EXPECT_THAT(err, IsEmpty());
1768}
1769
1770TEST_F(DumpstateUtilTest, FindingPidWithNotExistingProcess) {
1771 // find the process with abnormal name.
1772 EXPECT_EQ(-1, FindPidOfProcess("abcdef12345-543"));
1773 EXPECT_THAT(err, StrEq("can't find the pid\n"));
1774}
Felipe Leme47e9be22016-12-21 15:37:07 -08001775
1776} // namespace dumpstate
1777} // namespace os
1778} // namespace android