blob: c5d01fdf2562607dd073aab729115cad39d77c29 [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"));
Greg Kaiser3a811c12019-05-21 12:48:59 -0700667 // The duration may not get output, depending on how long it takes,
668 // so we just check the prefix.
Felipe Lemefd8affa2016-09-30 17:38:57 -0700669 EXPECT_THAT(out,
Nandana Dutt47527b52019-03-29 15:34:36 +0000670 StartsWith("------ I AM GROOT (" + kSimpleCommand + ") ------\nstdout\n"));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700671}
672
Felipe Lemefd8affa2016-09-30 17:38:57 -0700673TEST_F(DumpstateTest, RunCommandWithLoggingMessage) {
Felipe Leme4c2d6632016-09-28 14:32:00 -0700674 EXPECT_EQ(
Felipe Leme7447d7c2016-11-03 18:12:22 -0700675 0, RunCommand("", {kSimpleCommand},
Felipe Lemefd8affa2016-09-30 17:38:57 -0700676 CommandOptions::WithTimeout(10).Log("COMMAND, Y U NO LOG FIRST?").Build()));
677 EXPECT_THAT(out, StrEq("stdout\n"));
678 EXPECT_THAT(err, StrEq("COMMAND, Y U NO LOG FIRST?stderr\n"));
679}
680
681TEST_F(DumpstateTest, RunCommandRedirectStderr) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700682 EXPECT_EQ(0, RunCommand("", {kSimpleCommand},
Felipe Lemefd8affa2016-09-30 17:38:57 -0700683 CommandOptions::WithTimeout(10).RedirectStderr().Build()));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700684 EXPECT_THAT(out, IsEmpty());
Felipe Lemefd8affa2016-09-30 17:38:57 -0700685 EXPECT_THAT(err, StrEq("stdout\nstderr\n"));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700686}
687
688TEST_F(DumpstateTest, RunCommandWithOneArg) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700689 EXPECT_EQ(0, RunCommand("", {kEchoCommand, "one"}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700690 EXPECT_THAT(err, IsEmpty());
691 EXPECT_THAT(out, StrEq("one\n"));
692}
693
Felipe Lemefd8affa2016-09-30 17:38:57 -0700694TEST_F(DumpstateTest, RunCommandWithMultipleArgs) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700695 EXPECT_EQ(0, RunCommand("", {kEchoCommand, "one", "is", "the", "loniest", "number"}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700696 EXPECT_THAT(err, IsEmpty());
697 EXPECT_THAT(out, StrEq("one is the loniest number\n"));
698}
699
700TEST_F(DumpstateTest, RunCommandDryRun) {
701 SetDryRun(true);
Felipe Leme7447d7c2016-11-03 18:12:22 -0700702 EXPECT_EQ(0, RunCommand("I AM GROOT", {kSimpleCommand}));
Greg Kaiser3a811c12019-05-21 12:48:59 -0700703 // The duration may not get output, depending on how long it takes,
704 // so we just check the prefix.
Felipe Leme7447d7c2016-11-03 18:12:22 -0700705 EXPECT_THAT(out, StartsWith("------ I AM GROOT (" + kSimpleCommand +
Nandana Dutt47527b52019-03-29 15:34:36 +0000706 ") ------\n\t(skipped on dry run)\n"));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700707 EXPECT_THAT(err, IsEmpty());
708}
709
710TEST_F(DumpstateTest, RunCommandDryRunNoTitle) {
711 SetDryRun(true);
Felipe Leme7447d7c2016-11-03 18:12:22 -0700712 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700713 EXPECT_THAT(out, IsEmpty());
714 EXPECT_THAT(err, IsEmpty());
715}
716
717TEST_F(DumpstateTest, RunCommandDryRunAlways) {
718 SetDryRun(true);
Felipe Leme7447d7c2016-11-03 18:12:22 -0700719 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(10).Always().Build()));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700720 EXPECT_THAT(out, StrEq("stdout\n"));
721 EXPECT_THAT(err, StrEq("stderr\n"));
722}
723
Felipe Lemefd8affa2016-09-30 17:38:57 -0700724TEST_F(DumpstateTest, RunCommandNotFound) {
725 EXPECT_NE(0, RunCommand("", {"/there/cannot/be/such/command"}));
726 EXPECT_THAT(out, StartsWith("*** command '/there/cannot/be/such/command' failed: exit code"));
727 EXPECT_THAT(err, StartsWith("execvp on command '/there/cannot/be/such/command' failed"));
728}
729
730TEST_F(DumpstateTest, RunCommandFails) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700731 EXPECT_EQ(42, RunCommand("", {kSimpleCommand, "--exit", "42"}));
732 EXPECT_THAT(out, StrEq("stdout\n*** command '" + kSimpleCommand +
Felipe Leme9a523ae2016-10-20 15:10:33 -0700733 " --exit 42' failed: exit code 42\n"));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700734 EXPECT_THAT(err, StrEq("stderr\n*** command '" + kSimpleCommand +
Felipe Leme9a523ae2016-10-20 15:10:33 -0700735 " --exit 42' failed: exit code 42\n"));
Felipe Lemefd8affa2016-09-30 17:38:57 -0700736}
737
738TEST_F(DumpstateTest, RunCommandCrashes) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700739 EXPECT_NE(0, RunCommand("", {kSimpleCommand, "--crash"}));
Felipe Lemefd8affa2016-09-30 17:38:57 -0700740 // We don't know the exit code, so check just the prefix.
741 EXPECT_THAT(
Felipe Leme7447d7c2016-11-03 18:12:22 -0700742 out, StartsWith("stdout\n*** command '" + kSimpleCommand + " --crash' failed: exit code"));
Felipe Lemefd8affa2016-09-30 17:38:57 -0700743 EXPECT_THAT(
Felipe Leme7447d7c2016-11-03 18:12:22 -0700744 err, StartsWith("stderr\n*** command '" + kSimpleCommand + " --crash' failed: exit code"));
Felipe Lemefd8affa2016-09-30 17:38:57 -0700745}
746
747TEST_F(DumpstateTest, RunCommandTimesout) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700748 EXPECT_EQ(-1, RunCommand("", {kSimpleCommand, "--sleep", "2"},
Felipe Lemefd8affa2016-09-30 17:38:57 -0700749 CommandOptions::WithTimeout(1).Build()));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700750 EXPECT_THAT(out, StartsWith("stdout line1\n*** command '" + kSimpleCommand +
Felipe Lemefd8affa2016-09-30 17:38:57 -0700751 " --sleep 2' timed out after 1"));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700752 EXPECT_THAT(err, StartsWith("sleeping for 2s\n*** command '" + kSimpleCommand +
Felipe Lemefd8affa2016-09-30 17:38:57 -0700753 " --sleep 2' timed out after 1"));
754}
755
756TEST_F(DumpstateTest, RunCommandIsKilled) {
757 CaptureStdout();
758 CaptureStderr();
759
760 std::thread t([=]() {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700761 EXPECT_EQ(SIGTERM, ds.RunCommand("", {kSimpleCommand, "--pid", "--sleep", "20"},
Felipe Lemefd8affa2016-09-30 17:38:57 -0700762 CommandOptions::WithTimeout(100).Always().Build()));
763 });
764
765 // Capture pid and pre-sleep output.
766 sleep(1); // Wait a little bit to make sure pid and 1st line were printed.
767 std::string err = GetCapturedStderr();
768 EXPECT_THAT(err, StrEq("sleeping for 20s\n"));
769
770 std::string out = GetCapturedStdout();
771 std::vector<std::string> lines = android::base::Split(out, "\n");
772 ASSERT_EQ(3, (int)lines.size()) << "Invalid lines before sleep: " << out;
773
774 int pid = atoi(lines[0].c_str());
775 EXPECT_THAT(lines[1], StrEq("stdout line1"));
776 EXPECT_THAT(lines[2], IsEmpty()); // \n
777
778 // Then kill the process.
779 CaptureStdout();
780 CaptureStderr();
781 ASSERT_EQ(0, kill(pid, SIGTERM)) << "failed to kill pid " << pid;
782 t.join();
783
784 // Finally, check output after murder.
785 out = GetCapturedStdout();
786 err = GetCapturedStderr();
787
Felipe Leme7447d7c2016-11-03 18:12:22 -0700788 EXPECT_THAT(out, StrEq("*** command '" + kSimpleCommand +
Felipe Lemefd8affa2016-09-30 17:38:57 -0700789 " --pid --sleep 20' failed: killed by signal 15\n"));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700790 EXPECT_THAT(err, StrEq("*** command '" + kSimpleCommand +
Felipe Lemefd8affa2016-09-30 17:38:57 -0700791 " --pid --sleep 20' failed: killed by signal 15\n"));
792}
793
Felipe Leme75876a22016-10-27 16:31:27 -0700794TEST_F(DumpstateTest, RunCommandProgress) {
795 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
796 ds.listener_ = listener;
797 ds.listener_name_ = "FoxMulder";
Felipe Leme7447d7c2016-11-03 18:12:22 -0700798 SetProgress(0, 30);
Felipe Leme75876a22016-10-27 16:31:27 -0700799
800 EXPECT_CALL(*listener, onProgressUpdated(20));
Nandana Duttbabf6c72019-01-15 14:11:12 +0000801 EXPECT_CALL(*listener, onProgress(66)); // 20/30 %
Felipe Leme7447d7c2016-11-03 18:12:22 -0700802 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(20).Build()));
Felipe Leme75876a22016-10-27 16:31:27 -0700803 std::string progress_message = GetProgressMessage(ds.listener_name_, 20, 30);
804 EXPECT_THAT(out, StrEq("stdout\n"));
805 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
806
807 EXPECT_CALL(*listener, onProgressUpdated(30));
Nandana Duttbabf6c72019-01-15 14:11:12 +0000808 EXPECT_CALL(*listener, onProgress(100)); // 35/35 %
Felipe Leme7447d7c2016-11-03 18:12:22 -0700809 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(10).Build()));
Felipe Leme75876a22016-10-27 16:31:27 -0700810 progress_message = GetProgressMessage(ds.listener_name_, 30, 30);
811 EXPECT_THAT(out, StrEq("stdout\n"));
812 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
813
814 // Run a command that will increase maximum timeout.
815 EXPECT_CALL(*listener, onProgressUpdated(31));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700816 EXPECT_CALL(*listener, onMaxProgressUpdated(37));
Nandana Duttbabf6c72019-01-15 14:11:12 +0000817 EXPECT_CALL(*listener, onProgress(83)); // 31/37 %
Felipe Leme7447d7c2016-11-03 18:12:22 -0700818 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).Build()));
819 progress_message = GetProgressMessage(ds.listener_name_, 31, 37, 30); // 20% increase
Felipe Leme75876a22016-10-27 16:31:27 -0700820 EXPECT_THAT(out, StrEq("stdout\n"));
821 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
822
823 // Make sure command ran while in dry_run is counted.
824 SetDryRun(true);
825 EXPECT_CALL(*listener, onProgressUpdated(35));
Nandana Duttbabf6c72019-01-15 14:11:12 +0000826 EXPECT_CALL(*listener, onProgress(94)); // 35/37 %
Felipe Leme7447d7c2016-11-03 18:12:22 -0700827 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(4).Build()));
828 progress_message = GetProgressMessage(ds.listener_name_, 35, 37);
Felipe Leme75876a22016-10-27 16:31:27 -0700829 EXPECT_THAT(out, IsEmpty());
830 EXPECT_THAT(err, StrEq(progress_message));
831
832 ds.listener_.clear();
833}
834
Felipe Leme009ecbb2016-11-07 10:18:44 -0800835TEST_F(DumpstateTest, RunCommandProgressIgnoreThreshold) {
836 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
837 ds.listener_ = listener;
838 ds.listener_name_ = "FoxMulder";
839 SetProgress(0, 8, 5); // 8 max, 5 threshold
840
841 // First update should always be sent.
842 EXPECT_CALL(*listener, onProgressUpdated(1));
Nandana Duttbabf6c72019-01-15 14:11:12 +0000843 EXPECT_CALL(*listener, onProgress(12)); // 1/12 %
Felipe Leme009ecbb2016-11-07 10:18:44 -0800844 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).Build()));
845 std::string progress_message = GetProgressMessage(ds.listener_name_, 1, 8);
846 EXPECT_THAT(out, StrEq("stdout\n"));
847 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
848
849 // Fourth update should be ignored because it's between the threshold (5 -1 = 4 < 5).
850 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(4).Build()));
851 EXPECT_THAT(out, StrEq("stdout\n"));
852 EXPECT_THAT(err, StrEq("stderr\n"));
853
854 // Third update should be sent because it reaches threshold (6 - 1 = 5).
855 EXPECT_CALL(*listener, onProgressUpdated(6));
Nandana Duttbabf6c72019-01-15 14:11:12 +0000856 EXPECT_CALL(*listener, onProgress(75)); // 6/8 %
Felipe Leme009ecbb2016-11-07 10:18:44 -0800857 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).Build()));
858 progress_message = GetProgressMessage(ds.listener_name_, 6, 8);
859 EXPECT_THAT(out, StrEq("stdout\n"));
860 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
861
862 // Fourth update should be ignored because it's between the threshold (9 - 6 = 3 < 5).
863 // But max update should be sent.
864 EXPECT_CALL(*listener, onMaxProgressUpdated(10)); // 9 * 120% = 10.8 = 10
865 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(3).Build()));
866 progress_message = GetProgressMessage(ds.listener_name_, 9, 10, 8, false);
867 EXPECT_THAT(out, StrEq("stdout\n"));
868 EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
869
870 ds.listener_.clear();
871}
872
Felipe Lemed80e6b62016-10-03 13:08:14 -0700873TEST_F(DumpstateTest, RunCommandDropRoot) {
Felipe Leme46b85da2016-11-21 17:40:45 -0800874 if (!IsStandalone()) {
875 // TODO: temporarily disabled because it might cause other tests to fail after dropping
876 // to Shell - need to refactor tests to avoid this problem)
877 MYLOGE("Skipping DumpstateTest.RunCommandDropRoot() on test suite\n")
878 return;
879 }
Felipe Lemed80e6b62016-10-03 13:08:14 -0700880 // First check root case - only available when running with 'adb root'.
881 uid_t uid = getuid();
882 if (uid == 0) {
Felipe Leme7447d7c2016-11-03 18:12:22 -0700883 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"}));
Felipe Lemed80e6b62016-10-03 13:08:14 -0700884 EXPECT_THAT(out, StrEq("0\nstdout\n"));
885 EXPECT_THAT(err, StrEq("stderr\n"));
886 return;
887 }
Felipe Leme7447d7c2016-11-03 18:12:22 -0700888 // Then run dropping root.
889 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
Felipe Lemed80e6b62016-10-03 13:08:14 -0700890 CommandOptions::WithTimeout(1).DropRoot().Build()));
891 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
Felipe Leme26c41572016-10-06 14:34:43 -0700892 EXPECT_THAT(err, StrEq("drop_root_user(): already running as Shell\nstderr\n"));
Felipe Lemed80e6b62016-10-03 13:08:14 -0700893}
894
895TEST_F(DumpstateTest, RunCommandAsRootUserBuild) {
Felipe Leme46b85da2016-11-21 17:40:45 -0800896 if (!IsStandalone()) {
897 // TODO: temporarily disabled because it might cause other tests to fail after dropping
898 // to Shell - need to refactor tests to avoid this problem)
899 MYLOGE("Skipping DumpstateTest.RunCommandAsRootUserBuild() on test suite\n")
900 return;
901 }
Felipe Lemef0292972016-11-22 13:57:05 -0800902 if (!PropertiesHelper::IsUserBuild()) {
Felipe Lemed80e6b62016-10-03 13:08:14 -0700903 // Emulates user build if necessarily.
904 SetBuildType("user");
905 }
906
907 DropRoot();
908
Felipe Leme7447d7c2016-11-03 18:12:22 -0700909 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).AsRoot().Build()));
Felipe Lemed80e6b62016-10-03 13:08:14 -0700910
911 // We don't know the exact path of su, so we just check for the 'root ...' commands
912 EXPECT_THAT(out, StartsWith("Skipping"));
Felipe Leme7447d7c2016-11-03 18:12:22 -0700913 EXPECT_THAT(out, EndsWith("root " + kSimpleCommand + "' on user build.\n"));
Felipe Lemed80e6b62016-10-03 13:08:14 -0700914 EXPECT_THAT(err, IsEmpty());
915}
916
Felipe Leme46b85da2016-11-21 17:40:45 -0800917TEST_F(DumpstateTest, RunCommandAsRootNonUserBuild) {
918 if (!IsStandalone()) {
919 // TODO: temporarily disabled because it might cause other tests to fail after dropping
920 // to Shell - need to refactor tests to avoid this problem)
921 MYLOGE("Skipping DumpstateTest.RunCommandAsRootNonUserBuild() on test suite\n")
922 return;
923 }
Felipe Lemef0292972016-11-22 13:57:05 -0800924 if (PropertiesHelper::IsUserBuild()) {
Felipe Leme46b85da2016-11-21 17:40:45 -0800925 ALOGI("Skipping RunCommandAsRootNonUserBuild on user builds\n");
926 return;
927 }
928
929 DropRoot();
930
931 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
932 CommandOptions::WithTimeout(1).AsRoot().Build()));
933
934 EXPECT_THAT(out, StrEq("0\nstdout\n"));
935 EXPECT_THAT(err, StrEq("stderr\n"));
936}
937
Nandana Dutt4b392be2018-11-02 16:17:05 +0000938TEST_F(DumpstateTest, RunCommandAsRootNonUserBuild_withUnroot) {
939 if (!IsStandalone()) {
940 // TODO: temporarily disabled because it might cause other tests to fail after dropping
941 // to Shell - need to refactor tests to avoid this problem)
942 MYLOGE(
943 "Skipping DumpstateTest.RunCommandAsRootNonUserBuild_withUnroot() "
944 "on test suite\n")
945 return;
946 }
947 if (PropertiesHelper::IsUserBuild()) {
948 ALOGI("Skipping RunCommandAsRootNonUserBuild_withUnroot on user builds\n");
949 return;
950 }
951
952 // Same test as above, but with unroot property set, which will override su availability.
953 SetUnroot(true);
954 DropRoot();
955
956 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
957 CommandOptions::WithTimeout(1).AsRoot().Build()));
958
959 // AsRoot is ineffective.
960 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
961 EXPECT_THAT(err, StrEq("drop_root_user(): already running as Shell\nstderr\n"));
962}
963
Yifan Hong48e83a12017-10-03 14:10:07 -0700964TEST_F(DumpstateTest, RunCommandAsRootIfAvailableOnUserBuild) {
965 if (!IsStandalone()) {
966 // TODO: temporarily disabled because it might cause other tests to fail after dropping
967 // to Shell - need to refactor tests to avoid this problem)
968 MYLOGE("Skipping DumpstateTest.RunCommandAsRootIfAvailableOnUserBuild() on test suite\n")
969 return;
970 }
971 if (!PropertiesHelper::IsUserBuild()) {
972 // Emulates user build if necessarily.
973 SetBuildType("user");
974 }
975
976 DropRoot();
977
978 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
979 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
980
981 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
982 EXPECT_THAT(err, StrEq("stderr\n"));
983}
984
985TEST_F(DumpstateTest, RunCommandAsRootIfAvailableOnDebugBuild) {
986 if (!IsStandalone()) {
987 // TODO: temporarily disabled because it might cause other tests to fail after dropping
988 // to Shell - need to refactor tests to avoid this problem)
989 MYLOGE("Skipping DumpstateTest.RunCommandAsRootIfAvailableOnDebugBuild() on test suite\n")
990 return;
991 }
992 if (PropertiesHelper::IsUserBuild()) {
993 ALOGI("Skipping RunCommandAsRootNonUserBuild on user builds\n");
994 return;
995 }
996
997 DropRoot();
998
999 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
1000 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
1001
1002 EXPECT_THAT(out, StrEq("0\nstdout\n"));
1003 EXPECT_THAT(err, StrEq("stderr\n"));
1004}
1005
Nandana Dutt4b392be2018-11-02 16:17:05 +00001006TEST_F(DumpstateTest, RunCommandAsRootIfAvailableOnDebugBuild_withUnroot) {
1007 if (!IsStandalone()) {
1008 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1009 // to Shell - need to refactor tests to avoid this problem)
1010 MYLOGE(
1011 "Skipping DumpstateTest.RunCommandAsRootIfAvailableOnDebugBuild_withUnroot() "
1012 "on test suite\n")
1013 return;
1014 }
1015 if (PropertiesHelper::IsUserBuild()) {
1016 ALOGI("Skipping RunCommandAsRootIfAvailableOnDebugBuild_withUnroot on user builds\n");
1017 return;
1018 }
1019 // Same test as above, but with unroot property set, which will override su availability.
1020 SetUnroot(true);
1021
1022 DropRoot();
1023
1024 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
1025 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
1026
1027 // It's a userdebug build, so "su root" should be available, but unroot=true overrides it.
1028 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
1029 EXPECT_THAT(err, StrEq("stderr\n"));
1030}
1031
Felipe Lemecef02982016-10-03 17:22:22 -07001032TEST_F(DumpstateTest, DumpFileNotFoundNoTitle) {
1033 EXPECT_EQ(-1, DumpFile("", "/I/cant/believe/I/exist"));
1034 EXPECT_THAT(out,
1035 StrEq("*** Error dumping /I/cant/believe/I/exist: No such file or directory\n"));
1036 EXPECT_THAT(err, IsEmpty());
1037}
1038
1039TEST_F(DumpstateTest, DumpFileNotFoundWithTitle) {
1040 EXPECT_EQ(-1, DumpFile("Y U NO EXIST?", "/I/cant/believe/I/exist"));
1041 EXPECT_THAT(err, IsEmpty());
Greg Kaiser3a811c12019-05-21 12:48:59 -07001042 // The duration may not get output, depending on how long it takes,
1043 // so we just check the prefix.
Felipe Lemecef02982016-10-03 17:22:22 -07001044 EXPECT_THAT(out, StartsWith("*** Error dumping /I/cant/believe/I/exist (Y U NO EXIST?): No "
1045 "such file or directory\n"));
Felipe Lemecef02982016-10-03 17:22:22 -07001046}
1047
1048TEST_F(DumpstateTest, DumpFileSingleLine) {
Felipe Leme7447d7c2016-11-03 18:12:22 -07001049 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -07001050 EXPECT_THAT(err, IsEmpty());
1051 EXPECT_THAT(out, StrEq("I AM LINE1\n")); // dumpstate adds missing newline
1052}
1053
1054TEST_F(DumpstateTest, DumpFileSingleLineWithNewLine) {
Felipe Leme7447d7c2016-11-03 18:12:22 -07001055 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line-with-newline.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -07001056 EXPECT_THAT(err, IsEmpty());
1057 EXPECT_THAT(out, StrEq("I AM LINE1\n"));
1058}
1059
1060TEST_F(DumpstateTest, DumpFileMultipleLines) {
Felipe Leme7447d7c2016-11-03 18:12:22 -07001061 EXPECT_EQ(0, DumpFile("", kTestDataPath + "multiple-lines.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -07001062 EXPECT_THAT(err, IsEmpty());
1063 EXPECT_THAT(out, StrEq("I AM LINE1\nI AM LINE2\nI AM LINE3\n"));
1064}
1065
1066TEST_F(DumpstateTest, DumpFileMultipleLinesWithNewLine) {
Felipe Leme7447d7c2016-11-03 18:12:22 -07001067 EXPECT_EQ(0, DumpFile("", kTestDataPath + "multiple-lines-with-newline.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -07001068 EXPECT_THAT(err, IsEmpty());
1069 EXPECT_THAT(out, StrEq("I AM LINE1\nI AM LINE2\nI AM LINE3\n"));
1070}
1071
1072TEST_F(DumpstateTest, DumpFileOnDryRunNoTitle) {
1073 SetDryRun(true);
Felipe Leme7447d7c2016-11-03 18:12:22 -07001074 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -07001075 EXPECT_THAT(err, IsEmpty());
1076 EXPECT_THAT(out, IsEmpty());
1077}
1078
1079TEST_F(DumpstateTest, DumpFileOnDryRun) {
1080 SetDryRun(true);
Felipe Leme7447d7c2016-11-03 18:12:22 -07001081 EXPECT_EQ(0, DumpFile("Might as well dump. Dump!", kTestDataPath + "single-line.txt"));
Felipe Lemecef02982016-10-03 17:22:22 -07001082 EXPECT_THAT(err, IsEmpty());
Felipe Leme46b85da2016-11-21 17:40:45 -08001083 EXPECT_THAT(
1084 out, StartsWith("------ Might as well dump. Dump! (" + kTestDataPath + "single-line.txt:"));
Nandana Dutt47527b52019-03-29 15:34:36 +00001085 EXPECT_THAT(out, HasSubstr("\n\t(skipped on dry run)\n"));
Felipe Lemecef02982016-10-03 17:22:22 -07001086}
1087
Felipe Leme75876a22016-10-27 16:31:27 -07001088TEST_F(DumpstateTest, DumpFileUpdateProgress) {
1089 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
1090 ds.listener_ = listener;
1091 ds.listener_name_ = "FoxMulder";
Felipe Leme7447d7c2016-11-03 18:12:22 -07001092 SetProgress(0, 30);
Felipe Leme75876a22016-10-27 16:31:27 -07001093
1094 EXPECT_CALL(*listener, onProgressUpdated(5));
Nandana Duttbabf6c72019-01-15 14:11:12 +00001095 EXPECT_CALL(*listener, onProgress(16)); // 5/30 %
Felipe Leme7447d7c2016-11-03 18:12:22 -07001096 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
Felipe Leme75876a22016-10-27 16:31:27 -07001097
1098 std::string progress_message =
1099 GetProgressMessage(ds.listener_name_, 5, 30); // TODO: unhardcode WEIGHT_FILE (5)?
1100 EXPECT_THAT(err, StrEq(progress_message));
1101 EXPECT_THAT(out, StrEq("I AM LINE1\n")); // dumpstate adds missing newline
1102
1103 ds.listener_.clear();
1104}
1105
Felipe Leme7447d7c2016-11-03 18:12:22 -07001106class DumpstateServiceTest : public DumpstateBaseTest {
Felipe Leme75876a22016-10-27 16:31:27 -07001107 public:
1108 DumpstateService dss;
1109};
1110
1111TEST_F(DumpstateServiceTest, SetListenerNoName) {
1112 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
Felipe Leme009ecbb2016-11-07 10:18:44 -08001113 sp<IDumpstateToken> token;
Vishnu Nair20cf5032018-01-05 13:15:49 -08001114 EXPECT_TRUE(dss.setListener("", listener, /* getSectionDetails = */ false, &token).isOk());
Felipe Leme009ecbb2016-11-07 10:18:44 -08001115 ASSERT_THAT(token, IsNull());
Felipe Leme75876a22016-10-27 16:31:27 -07001116}
1117
1118TEST_F(DumpstateServiceTest, SetListenerNoPointer) {
Felipe Leme009ecbb2016-11-07 10:18:44 -08001119 sp<IDumpstateToken> token;
Vishnu Nair20cf5032018-01-05 13:15:49 -08001120 EXPECT_TRUE(
1121 dss.setListener("whatever", nullptr, /* getSectionDetails = */ false, &token).isOk());
Felipe Leme009ecbb2016-11-07 10:18:44 -08001122 ASSERT_THAT(token, IsNull());
Felipe Leme75876a22016-10-27 16:31:27 -07001123}
1124
1125TEST_F(DumpstateServiceTest, SetListenerTwice) {
1126 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
Felipe Leme009ecbb2016-11-07 10:18:44 -08001127 sp<IDumpstateToken> token;
Vishnu Nair20cf5032018-01-05 13:15:49 -08001128 EXPECT_TRUE(
1129 dss.setListener("whatever", listener, /* getSectionDetails = */ false, &token).isOk());
Felipe Leme009ecbb2016-11-07 10:18:44 -08001130 ASSERT_THAT(token, NotNull());
Felipe Leme75876a22016-10-27 16:31:27 -07001131 EXPECT_THAT(Dumpstate::GetInstance().listener_name_, StrEq("whatever"));
Vishnu Nair20cf5032018-01-05 13:15:49 -08001132 EXPECT_FALSE(Dumpstate::GetInstance().report_section_);
Felipe Leme75876a22016-10-27 16:31:27 -07001133
Felipe Leme009ecbb2016-11-07 10:18:44 -08001134 token.clear();
Vishnu Nair20cf5032018-01-05 13:15:49 -08001135 EXPECT_TRUE(
1136 dss.setListener("whatsoever", listener, /* getSectionDetails = */ false, &token).isOk());
Felipe Leme009ecbb2016-11-07 10:18:44 -08001137 ASSERT_THAT(token, IsNull());
1138 EXPECT_THAT(Dumpstate::GetInstance().listener_name_, StrEq("whatever"));
Vishnu Nair20cf5032018-01-05 13:15:49 -08001139 EXPECT_FALSE(Dumpstate::GetInstance().report_section_);
1140}
1141
1142TEST_F(DumpstateServiceTest, SetListenerWithSectionDetails) {
1143 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
1144 sp<IDumpstateToken> token;
1145 Dumpstate::GetInstance().listener_ = nullptr;
1146 EXPECT_TRUE(
1147 dss.setListener("whatever", listener, /* getSectionDetails = */ true, &token).isOk());
1148 ASSERT_THAT(token, NotNull());
1149 EXPECT_THAT(Dumpstate::GetInstance().listener_name_, StrEq("whatever"));
1150 EXPECT_TRUE(Dumpstate::GetInstance().report_section_);
Felipe Leme75876a22016-10-27 16:31:27 -07001151}
Felipe Leme7447d7c2016-11-03 18:12:22 -07001152
1153class ProgressTest : public DumpstateBaseTest {
1154 public:
1155 Progress GetInstance(int32_t max, double growth_factor, const std::string& path = "") {
1156 return Progress(max, growth_factor, path);
1157 }
1158
1159 void AssertStats(const std::string& path, int32_t expected_runs, int32_t expected_average) {
1160 std::string expected_content =
1161 android::base::StringPrintf("%d %d\n", expected_runs, expected_average);
1162 std::string actual_content;
Felipe Leme46b85da2016-11-21 17:40:45 -08001163 ReadFileToString(path, &actual_content);
Felipe Leme7447d7c2016-11-03 18:12:22 -07001164 ASSERT_THAT(actual_content, StrEq(expected_content)) << "invalid stats on " << path;
1165 }
1166};
1167
1168TEST_F(ProgressTest, SimpleTest) {
1169 Progress progress;
1170 EXPECT_EQ(0, progress.Get());
1171 EXPECT_EQ(Progress::kDefaultMax, progress.GetInitialMax());
1172 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1173
1174 bool max_increased = progress.Inc(1);
1175 EXPECT_EQ(1, progress.Get());
1176 EXPECT_EQ(Progress::kDefaultMax, progress.GetInitialMax());
1177 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1178 EXPECT_FALSE(max_increased);
1179
1180 // Ignore negative increase.
1181 max_increased = progress.Inc(-1);
1182 EXPECT_EQ(1, progress.Get());
1183 EXPECT_EQ(Progress::kDefaultMax, progress.GetInitialMax());
1184 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1185 EXPECT_FALSE(max_increased);
1186}
1187
1188TEST_F(ProgressTest, MaxGrowsInsideNewRange) {
1189 Progress progress = GetInstance(10, 1.2); // 20% growth factor
1190 EXPECT_EQ(0, progress.Get());
1191 EXPECT_EQ(10, progress.GetInitialMax());
1192 EXPECT_EQ(10, progress.GetMax());
1193
1194 // No increase
1195 bool max_increased = progress.Inc(10);
1196 EXPECT_EQ(10, progress.Get());
1197 EXPECT_EQ(10, progress.GetMax());
1198 EXPECT_FALSE(max_increased);
1199
1200 // Increase, with new value < max*20%
1201 max_increased = progress.Inc(1);
1202 EXPECT_EQ(11, progress.Get());
1203 EXPECT_EQ(13, progress.GetMax()); // 11 average * 20% growth = 13.2 = 13
1204 EXPECT_TRUE(max_increased);
1205}
1206
1207TEST_F(ProgressTest, MaxGrowsOutsideNewRange) {
1208 Progress progress = GetInstance(10, 1.2); // 20% growth factor
1209 EXPECT_EQ(0, progress.Get());
1210 EXPECT_EQ(10, progress.GetInitialMax());
1211 EXPECT_EQ(10, progress.GetMax());
1212
1213 // No increase
1214 bool max_increased = progress.Inc(10);
1215 EXPECT_EQ(10, progress.Get());
1216 EXPECT_EQ(10, progress.GetMax());
1217 EXPECT_FALSE(max_increased);
1218
1219 // Increase, with new value > max*20%
1220 max_increased = progress.Inc(5);
1221 EXPECT_EQ(15, progress.Get());
1222 EXPECT_EQ(18, progress.GetMax()); // 15 average * 20% growth = 18
1223 EXPECT_TRUE(max_increased);
1224}
1225
1226TEST_F(ProgressTest, InvalidPath) {
1227 Progress progress("/devil/null");
1228 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1229}
1230
1231TEST_F(ProgressTest, EmptyFile) {
1232 Progress progress(CopyTextFileFixture("empty-file.txt"));
1233 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1234}
1235
1236TEST_F(ProgressTest, InvalidLine1stEntryNAN) {
1237 Progress progress(CopyTextFileFixture("stats-invalid-1st-NAN.txt"));
1238 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1239}
1240
1241TEST_F(ProgressTest, InvalidLine2ndEntryNAN) {
1242 Progress progress(CopyTextFileFixture("stats-invalid-2nd-NAN.txt"));
1243 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1244}
1245
1246TEST_F(ProgressTest, InvalidLineBothNAN) {
1247 Progress progress(CopyTextFileFixture("stats-invalid-both-NAN.txt"));
1248 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1249}
1250
1251TEST_F(ProgressTest, InvalidLine1stEntryNegative) {
1252 Progress progress(CopyTextFileFixture("stats-invalid-1st-negative.txt"));
1253 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1254}
1255
1256TEST_F(ProgressTest, InvalidLine2ndEntryNegative) {
1257 Progress progress(CopyTextFileFixture("stats-invalid-2nd-negative.txt"));
1258 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1259}
1260
1261TEST_F(ProgressTest, InvalidLine1stEntryTooBig) {
1262 Progress progress(CopyTextFileFixture("stats-invalid-1st-too-big.txt"));
1263 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1264}
1265
1266TEST_F(ProgressTest, InvalidLine2ndEntryTooBig) {
1267 Progress progress(CopyTextFileFixture("stats-invalid-2nd-too-big.txt"));
1268 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1269}
1270
1271// Tests stats are properly saved when the file does not exists.
1272TEST_F(ProgressTest, FirstTime) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001273 if (!IsStandalone()) {
1274 // TODO: temporarily disabled because it's failing when running as suite
1275 MYLOGE("Skipping ProgressTest.FirstTime() on test suite\n")
1276 return;
1277 }
1278
Felipe Leme7447d7c2016-11-03 18:12:22 -07001279 std::string path = kTestDataPath + "FirstTime.txt";
1280 android::base::RemoveFileIfExists(path);
1281
1282 Progress run1(path);
1283 EXPECT_EQ(0, run1.Get());
1284 EXPECT_EQ(Progress::kDefaultMax, run1.GetInitialMax());
1285 EXPECT_EQ(Progress::kDefaultMax, run1.GetMax());
1286
1287 bool max_increased = run1.Inc(20);
1288 EXPECT_EQ(20, run1.Get());
1289 EXPECT_EQ(Progress::kDefaultMax, run1.GetMax());
1290 EXPECT_FALSE(max_increased);
1291
1292 run1.Save();
1293 AssertStats(path, 1, 20);
1294}
1295
1296// Tests what happens when the persistent settings contains the average duration of 1 run.
1297// Data on file is 1 run and 109 average.
1298TEST_F(ProgressTest, SecondTime) {
1299 std::string path = CopyTextFileFixture("stats-one-run-no-newline.txt");
1300
1301 Progress run1 = GetInstance(-42, 1.2, path);
1302 EXPECT_EQ(0, run1.Get());
1303 EXPECT_EQ(10, run1.GetInitialMax());
1304 EXPECT_EQ(10, run1.GetMax());
1305
1306 bool max_increased = run1.Inc(20);
1307 EXPECT_EQ(20, run1.Get());
1308 EXPECT_EQ(24, run1.GetMax());
1309 EXPECT_TRUE(max_increased);
1310
1311 // Average now is 2 runs and (10 + 20)/ 2 = 15
1312 run1.Save();
1313 AssertStats(path, 2, 15);
1314
1315 Progress run2 = GetInstance(-42, 1.2, path);
1316 EXPECT_EQ(0, run2.Get());
1317 EXPECT_EQ(15, run2.GetInitialMax());
1318 EXPECT_EQ(15, run2.GetMax());
1319
1320 max_increased = run2.Inc(25);
1321 EXPECT_EQ(25, run2.Get());
1322 EXPECT_EQ(30, run2.GetMax());
1323 EXPECT_TRUE(max_increased);
1324
1325 // Average now is 3 runs and (15 * 2 + 25)/ 3 = 18.33 = 18
1326 run2.Save();
1327 AssertStats(path, 3, 18);
1328
1329 Progress run3 = GetInstance(-42, 1.2, path);
1330 EXPECT_EQ(0, run3.Get());
1331 EXPECT_EQ(18, run3.GetInitialMax());
1332 EXPECT_EQ(18, run3.GetMax());
1333
1334 // Make sure average decreases as well
1335 max_increased = run3.Inc(5);
1336 EXPECT_EQ(5, run3.Get());
1337 EXPECT_EQ(18, run3.GetMax());
1338 EXPECT_FALSE(max_increased);
1339
1340 // Average now is 4 runs and (18 * 3 + 5)/ 4 = 14.75 = 14
1341 run3.Save();
1342 AssertStats(path, 4, 14);
1343}
1344
1345// Tests what happens when the persistent settings contains the average duration of 2 runs.
1346// Data on file is 2 runs and 15 average.
1347TEST_F(ProgressTest, ThirdTime) {
1348 std::string path = CopyTextFileFixture("stats-two-runs.txt");
1349 AssertStats(path, 2, 15); // Sanity check
1350
1351 Progress run1 = GetInstance(-42, 1.2, path);
1352 EXPECT_EQ(0, run1.Get());
1353 EXPECT_EQ(15, run1.GetInitialMax());
1354 EXPECT_EQ(15, run1.GetMax());
1355
1356 bool max_increased = run1.Inc(20);
1357 EXPECT_EQ(20, run1.Get());
1358 EXPECT_EQ(24, run1.GetMax());
1359 EXPECT_TRUE(max_increased);
1360
1361 // Average now is 3 runs and (15 * 2 + 20)/ 3 = 16.66 = 16
1362 run1.Save();
1363 AssertStats(path, 3, 16);
1364}
1365
Felipe Leme46b85da2016-11-21 17:40:45 -08001366class DumpstateUtilTest : public DumpstateBaseTest {
1367 public:
1368 void SetUp() {
1369 DumpstateBaseTest::SetUp();
1370 SetDryRun(false);
1371 }
1372
Felipe Leme46b85da2016-11-21 17:40:45 -08001373 void CaptureFdOut() {
Felipe Lemef0292972016-11-22 13:57:05 -08001374 ReadFileToString(path_, &out);
Felipe Leme46b85da2016-11-21 17:40:45 -08001375 }
1376
1377 void CreateFd(const std::string& name) {
1378 path_ = kTestDataPath + name;
1379 MYLOGD("Creating fd for file %s\n", path_.c_str());
1380
1381 fd = TEMP_FAILURE_RETRY(open(path_.c_str(),
1382 O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW,
1383 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH));
1384 ASSERT_GE(fd, 0) << "could not create FD for path " << path_;
1385 }
1386
1387 // Runs a command into the `fd` and capture `stderr`.
Felipe Lemef0292972016-11-22 13:57:05 -08001388 int RunCommand(const std::string& title, const std::vector<std::string>& full_command,
Felipe Leme46b85da2016-11-21 17:40:45 -08001389 const CommandOptions& options = CommandOptions::DEFAULT) {
1390 CaptureStderr();
Felipe Lemef0292972016-11-22 13:57:05 -08001391 int status = RunCommandToFd(fd, title, full_command, options);
Felipe Leme46b85da2016-11-21 17:40:45 -08001392 close(fd);
1393
1394 CaptureFdOut();
1395 err = GetCapturedStderr();
1396 return status;
1397 }
1398
1399 // Dumps a file and into the `fd` and `stderr`.
Felipe Lemef0292972016-11-22 13:57:05 -08001400 int DumpFile(const std::string& title, const std::string& path) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001401 CaptureStderr();
Felipe Lemef0292972016-11-22 13:57:05 -08001402 int status = DumpFileToFd(fd, title, path);
Felipe Leme46b85da2016-11-21 17:40:45 -08001403 close(fd);
1404
1405 CaptureFdOut();
1406 err = GetCapturedStderr();
1407 return status;
1408 }
1409
Ecco Park61ffcf72016-10-27 15:46:26 -07001410 // Find out the pid of the process_name
1411 int FindPidOfProcess(const std::string& process_name) {
1412 CaptureStderr();
1413 int status = GetPidByName(process_name);
1414 err = GetCapturedStderr();
1415 return status;
1416 }
1417
Felipe Leme46b85da2016-11-21 17:40:45 -08001418 int fd;
1419
1420 // 'fd` output and `stderr` from the last command ran.
1421 std::string out, err;
1422
1423 private:
1424 std::string path_;
1425};
1426
1427TEST_F(DumpstateUtilTest, RunCommandNoArgs) {
Felipe Lemef0292972016-11-22 13:57:05 -08001428 CreateFd("RunCommandNoArgs.txt");
1429 EXPECT_EQ(-1, RunCommand("", {}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001430}
1431
Felipe Lemef0292972016-11-22 13:57:05 -08001432TEST_F(DumpstateUtilTest, RunCommandNoTitle) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001433 CreateFd("RunCommandWithNoArgs.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001434 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001435 EXPECT_THAT(out, StrEq("stdout\n"));
1436 EXPECT_THAT(err, StrEq("stderr\n"));
1437}
1438
Felipe Lemef0292972016-11-22 13:57:05 -08001439TEST_F(DumpstateUtilTest, RunCommandWithTitle) {
1440 CreateFd("RunCommandWithNoArgs.txt");
1441 EXPECT_EQ(0, RunCommand("I AM GROOT", {kSimpleCommand}));
1442 EXPECT_THAT(out, StrEq("------ I AM GROOT (" + kSimpleCommand + ") ------\nstdout\n"));
1443 EXPECT_THAT(err, StrEq("stderr\n"));
1444}
1445
Felipe Leme46b85da2016-11-21 17:40:45 -08001446TEST_F(DumpstateUtilTest, RunCommandWithOneArg) {
1447 CreateFd("RunCommandWithOneArg.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001448 EXPECT_EQ(0, RunCommand("", {kEchoCommand, "one"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001449 EXPECT_THAT(err, IsEmpty());
1450 EXPECT_THAT(out, StrEq("one\n"));
1451}
1452
1453TEST_F(DumpstateUtilTest, RunCommandWithMultipleArgs) {
1454 CreateFd("RunCommandWithMultipleArgs.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001455 EXPECT_EQ(0, RunCommand("", {kEchoCommand, "one", "is", "the", "loniest", "number"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001456 EXPECT_THAT(err, IsEmpty());
1457 EXPECT_THAT(out, StrEq("one is the loniest number\n"));
1458}
1459
1460TEST_F(DumpstateUtilTest, RunCommandWithLoggingMessage) {
1461 CreateFd("RunCommandWithLoggingMessage.txt");
1462 EXPECT_EQ(
Felipe Lemef0292972016-11-22 13:57:05 -08001463 0, RunCommand("", {kSimpleCommand},
Felipe Leme46b85da2016-11-21 17:40:45 -08001464 CommandOptions::WithTimeout(10).Log("COMMAND, Y U NO LOG FIRST?").Build()));
1465 EXPECT_THAT(out, StrEq("stdout\n"));
1466 EXPECT_THAT(err, StrEq("COMMAND, Y U NO LOG FIRST?stderr\n"));
1467}
1468
1469TEST_F(DumpstateUtilTest, RunCommandRedirectStderr) {
1470 CreateFd("RunCommandRedirectStderr.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001471 EXPECT_EQ(0, RunCommand("", {kSimpleCommand},
1472 CommandOptions::WithTimeout(10).RedirectStderr().Build()));
Felipe Leme46b85da2016-11-21 17:40:45 -08001473 EXPECT_THAT(out, IsEmpty());
1474 EXPECT_THAT(err, StrEq("stdout\nstderr\n"));
1475}
1476
1477TEST_F(DumpstateUtilTest, RunCommandDryRun) {
1478 CreateFd("RunCommandDryRun.txt");
1479 SetDryRun(true);
Felipe Lemef0292972016-11-22 13:57:05 -08001480 EXPECT_EQ(0, RunCommand("I AM GROOT", {kSimpleCommand}));
1481 EXPECT_THAT(out, StrEq(android::base::StringPrintf(
1482 "------ I AM GROOT (%s) ------\n\t(skipped on dry run)\n",
1483 kSimpleCommand.c_str())));
1484 EXPECT_THAT(err, IsEmpty());
1485}
1486
1487TEST_F(DumpstateUtilTest, RunCommandDryRunNoTitle) {
1488 CreateFd("RunCommandDryRun.txt");
1489 SetDryRun(true);
1490 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001491 EXPECT_THAT(
1492 out, StrEq(android::base::StringPrintf("%s: skipped on dry run\n", kSimpleCommand.c_str())));
1493 EXPECT_THAT(err, IsEmpty());
1494}
1495
1496TEST_F(DumpstateUtilTest, RunCommandDryRunAlways) {
1497 CreateFd("RunCommandDryRunAlways.txt");
1498 SetDryRun(true);
Felipe Lemef0292972016-11-22 13:57:05 -08001499 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(10).Always().Build()));
Felipe Leme46b85da2016-11-21 17:40:45 -08001500 EXPECT_THAT(out, StrEq("stdout\n"));
1501 EXPECT_THAT(err, StrEq("stderr\n"));
1502}
1503
1504TEST_F(DumpstateUtilTest, RunCommandNotFound) {
1505 CreateFd("RunCommandNotFound.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001506 EXPECT_NE(0, RunCommand("", {"/there/cannot/be/such/command"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001507 EXPECT_THAT(out, StartsWith("*** command '/there/cannot/be/such/command' failed: exit code"));
1508 EXPECT_THAT(err, StartsWith("execvp on command '/there/cannot/be/such/command' failed"));
1509}
1510
1511TEST_F(DumpstateUtilTest, RunCommandFails) {
1512 CreateFd("RunCommandFails.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001513 EXPECT_EQ(42, RunCommand("", {kSimpleCommand, "--exit", "42"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001514 EXPECT_THAT(out, StrEq("stdout\n*** command '" + kSimpleCommand +
1515 " --exit 42' failed: exit code 42\n"));
1516 EXPECT_THAT(err, StrEq("stderr\n*** command '" + kSimpleCommand +
1517 " --exit 42' failed: exit code 42\n"));
1518}
1519
1520TEST_F(DumpstateUtilTest, RunCommandCrashes) {
1521 CreateFd("RunCommandCrashes.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001522 EXPECT_NE(0, RunCommand("", {kSimpleCommand, "--crash"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001523 // We don't know the exit code, so check just the prefix.
1524 EXPECT_THAT(
1525 out, StartsWith("stdout\n*** command '" + kSimpleCommand + " --crash' failed: exit code"));
1526 EXPECT_THAT(
1527 err, StartsWith("stderr\n*** command '" + kSimpleCommand + " --crash' failed: exit code"));
1528}
1529
Vishnu Nair6921f802017-11-22 09:17:23 -08001530TEST_F(DumpstateUtilTest, RunCommandTimesoutWithSec) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001531 CreateFd("RunCommandTimesout.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001532 EXPECT_EQ(-1, RunCommand("", {kSimpleCommand, "--sleep", "2"},
1533 CommandOptions::WithTimeout(1).Build()));
Felipe Leme46b85da2016-11-21 17:40:45 -08001534 EXPECT_THAT(out, StartsWith("stdout line1\n*** command '" + kSimpleCommand +
1535 " --sleep 2' timed out after 1"));
1536 EXPECT_THAT(err, StartsWith("sleeping for 2s\n*** command '" + kSimpleCommand +
1537 " --sleep 2' timed out after 1"));
1538}
1539
Vishnu Nair6921f802017-11-22 09:17:23 -08001540TEST_F(DumpstateUtilTest, RunCommandTimesoutWithMsec) {
1541 CreateFd("RunCommandTimesout.txt");
1542 EXPECT_EQ(-1, RunCommand("", {kSimpleCommand, "--sleep", "2"},
1543 CommandOptions::WithTimeoutInMs(1000).Build()));
1544 EXPECT_THAT(out, StartsWith("stdout line1\n*** command '" + kSimpleCommand +
1545 " --sleep 2' timed out after 1"));
1546 EXPECT_THAT(err, StartsWith("sleeping for 2s\n*** command '" + kSimpleCommand +
1547 " --sleep 2' timed out after 1"));
1548}
1549
1550
Felipe Leme46b85da2016-11-21 17:40:45 -08001551TEST_F(DumpstateUtilTest, RunCommandIsKilled) {
1552 CreateFd("RunCommandIsKilled.txt");
1553 CaptureStderr();
1554
1555 std::thread t([=]() {
Felipe Lemef0292972016-11-22 13:57:05 -08001556 EXPECT_EQ(SIGTERM, RunCommandToFd(fd, "", {kSimpleCommand, "--pid", "--sleep", "20"},
Felipe Leme46b85da2016-11-21 17:40:45 -08001557 CommandOptions::WithTimeout(100).Always().Build()));
1558 });
1559
1560 // Capture pid and pre-sleep output.
1561 sleep(1); // Wait a little bit to make sure pid and 1st line were printed.
1562 std::string err = GetCapturedStderr();
1563 EXPECT_THAT(err, StrEq("sleeping for 20s\n"));
1564
1565 CaptureFdOut();
1566 std::vector<std::string> lines = android::base::Split(out, "\n");
1567 ASSERT_EQ(3, (int)lines.size()) << "Invalid lines before sleep: " << out;
1568
1569 int pid = atoi(lines[0].c_str());
1570 EXPECT_THAT(lines[1], StrEq("stdout line1"));
1571 EXPECT_THAT(lines[2], IsEmpty()); // \n
1572
1573 // Then kill the process.
1574 CaptureFdOut();
1575 CaptureStderr();
1576 ASSERT_EQ(0, kill(pid, SIGTERM)) << "failed to kill pid " << pid;
1577 t.join();
1578
1579 // Finally, check output after murder.
1580 CaptureFdOut();
1581 err = GetCapturedStderr();
1582
1583 // out starts with the pid, which is an unknown
1584 EXPECT_THAT(out, EndsWith("stdout line1\n*** command '" + kSimpleCommand +
1585 " --pid --sleep 20' failed: killed by signal 15\n"));
1586 EXPECT_THAT(err, StrEq("*** command '" + kSimpleCommand +
1587 " --pid --sleep 20' failed: killed by signal 15\n"));
1588}
1589
1590TEST_F(DumpstateUtilTest, RunCommandAsRootUserBuild) {
1591 if (!IsStandalone()) {
1592 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1593 // to Shell - need to refactor tests to avoid this problem)
1594 MYLOGE("Skipping DumpstateUtilTest.RunCommandAsRootUserBuild() on test suite\n")
1595 return;
1596 }
1597 CreateFd("RunCommandAsRootUserBuild.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001598 if (!PropertiesHelper::IsUserBuild()) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001599 // Emulates user build if necessarily.
1600 SetBuildType("user");
1601 }
1602
1603 DropRoot();
1604
Felipe Lemef0292972016-11-22 13:57:05 -08001605 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).AsRoot().Build()));
Felipe Leme46b85da2016-11-21 17:40:45 -08001606
1607 // We don't know the exact path of su, so we just check for the 'root ...' commands
1608 EXPECT_THAT(out, StartsWith("Skipping"));
1609 EXPECT_THAT(out, EndsWith("root " + kSimpleCommand + "' on user build.\n"));
1610 EXPECT_THAT(err, IsEmpty());
1611}
1612
1613TEST_F(DumpstateUtilTest, RunCommandAsRootNonUserBuild) {
1614 if (!IsStandalone()) {
1615 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1616 // to Shell - need to refactor tests to avoid this problem)
1617 MYLOGE("Skipping DumpstateUtilTest.RunCommandAsRootNonUserBuild() on test suite\n")
1618 return;
1619 }
1620 CreateFd("RunCommandAsRootNonUserBuild.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001621 if (PropertiesHelper::IsUserBuild()) {
Felipe Leme7447d7c2016-11-03 18:12:22 -07001622 ALOGI("Skipping RunCommandAsRootNonUserBuild on user builds\n");
1623 return;
1624 }
1625
1626 DropRoot();
1627
Felipe Lemef0292972016-11-22 13:57:05 -08001628 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
1629 CommandOptions::WithTimeout(1).AsRoot().Build()));
Felipe Leme7447d7c2016-11-03 18:12:22 -07001630
1631 EXPECT_THAT(out, StrEq("0\nstdout\n"));
1632 EXPECT_THAT(err, StrEq("stderr\n"));
1633}
Felipe Leme46b85da2016-11-21 17:40:45 -08001634
Yifan Hong48e83a12017-10-03 14:10:07 -07001635
1636TEST_F(DumpstateUtilTest, RunCommandAsRootIfAvailableOnUserBuild) {
1637 if (!IsStandalone()) {
1638 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1639 // to Shell - need to refactor tests to avoid this problem)
1640 MYLOGE("Skipping DumpstateUtilTest.RunCommandAsRootIfAvailableOnUserBuild() on test suite\n")
1641 return;
1642 }
1643 CreateFd("RunCommandAsRootIfAvailableOnUserBuild.txt");
1644 if (!PropertiesHelper::IsUserBuild()) {
1645 // Emulates user build if necessarily.
1646 SetBuildType("user");
1647 }
1648
1649 DropRoot();
1650
1651 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
1652 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
1653
1654 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
1655 EXPECT_THAT(err, StrEq("stderr\n"));
1656}
1657
1658TEST_F(DumpstateUtilTest, RunCommandAsRootIfAvailableOnDebugBuild) {
1659 if (!IsStandalone()) {
1660 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1661 // to Shell - need to refactor tests to avoid this problem)
1662 MYLOGE("Skipping DumpstateUtilTest.RunCommandAsRootIfAvailableOnDebugBuild() on test suite\n")
1663 return;
1664 }
1665 CreateFd("RunCommandAsRootIfAvailableOnDebugBuild.txt");
1666 if (PropertiesHelper::IsUserBuild()) {
1667 ALOGI("Skipping RunCommandAsRootNonUserBuild on user builds\n");
1668 return;
1669 }
1670
1671 DropRoot();
1672
1673 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
1674 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
1675
1676 EXPECT_THAT(out, StrEq("0\nstdout\n"));
1677 EXPECT_THAT(err, StrEq("stderr\n"));
1678}
1679
Felipe Leme46b85da2016-11-21 17:40:45 -08001680TEST_F(DumpstateUtilTest, RunCommandDropRoot) {
1681 if (!IsStandalone()) {
1682 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1683 // to Shell - need to refactor tests to avoid this problem)
1684 MYLOGE("Skipping DumpstateUtilTest.RunCommandDropRoot() on test suite\n")
1685 return;
1686 }
1687 CreateFd("RunCommandDropRoot.txt");
1688 // First check root case - only available when running with 'adb root'.
1689 uid_t uid = getuid();
1690 if (uid == 0) {
Felipe Lemef0292972016-11-22 13:57:05 -08001691 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001692 EXPECT_THAT(out, StrEq("0\nstdout\n"));
1693 EXPECT_THAT(err, StrEq("stderr\n"));
1694 return;
1695 }
1696 // Then run dropping root.
Felipe Lemef0292972016-11-22 13:57:05 -08001697 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
Felipe Leme46b85da2016-11-21 17:40:45 -08001698 CommandOptions::WithTimeout(1).DropRoot().Build()));
1699 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
1700 EXPECT_THAT(err, StrEq("drop_root_user(): already running as Shell\nstderr\n"));
1701}
1702
Felipe Lemef0292972016-11-22 13:57:05 -08001703TEST_F(DumpstateUtilTest, DumpFileNotFoundNoTitle) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001704 CreateFd("DumpFileNotFound.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001705 EXPECT_EQ(-1, DumpFile("", "/I/cant/believe/I/exist"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001706 EXPECT_THAT(out,
1707 StrEq("*** Error dumping /I/cant/believe/I/exist: No such file or directory\n"));
1708 EXPECT_THAT(err, IsEmpty());
1709}
1710
Felipe Lemef0292972016-11-22 13:57:05 -08001711TEST_F(DumpstateUtilTest, DumpFileNotFoundWithTitle) {
1712 CreateFd("DumpFileNotFound.txt");
1713 EXPECT_EQ(-1, DumpFile("Y U NO EXIST?", "/I/cant/believe/I/exist"));
1714 EXPECT_THAT(out, StrEq("*** Error dumping /I/cant/believe/I/exist (Y U NO EXIST?): No such "
1715 "file or directory\n"));
1716 EXPECT_THAT(err, IsEmpty());
1717}
1718
Felipe Leme46b85da2016-11-21 17:40:45 -08001719TEST_F(DumpstateUtilTest, DumpFileSingleLine) {
1720 CreateFd("DumpFileSingleLine.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001721 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001722 EXPECT_THAT(err, IsEmpty());
1723 EXPECT_THAT(out, StrEq("I AM LINE1\n")); // dumpstate adds missing newline
1724}
1725
1726TEST_F(DumpstateUtilTest, DumpFileSingleLineWithNewLine) {
1727 CreateFd("DumpFileSingleLineWithNewLine.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001728 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line-with-newline.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001729 EXPECT_THAT(err, IsEmpty());
1730 EXPECT_THAT(out, StrEq("I AM LINE1\n"));
1731}
1732
1733TEST_F(DumpstateUtilTest, DumpFileMultipleLines) {
1734 CreateFd("DumpFileMultipleLines.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001735 EXPECT_EQ(0, DumpFile("", kTestDataPath + "multiple-lines.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001736 EXPECT_THAT(err, IsEmpty());
1737 EXPECT_THAT(out, StrEq("I AM LINE1\nI AM LINE2\nI AM LINE3\n"));
1738}
1739
1740TEST_F(DumpstateUtilTest, DumpFileMultipleLinesWithNewLine) {
1741 CreateFd("DumpFileMultipleLinesWithNewLine.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001742 EXPECT_EQ(0, DumpFile("", kTestDataPath + "multiple-lines-with-newline.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001743 EXPECT_THAT(err, IsEmpty());
1744 EXPECT_THAT(out, StrEq("I AM LINE1\nI AM LINE2\nI AM LINE3\n"));
1745}
1746
Felipe Lemef0292972016-11-22 13:57:05 -08001747TEST_F(DumpstateUtilTest, DumpFileOnDryRunNoTitle) {
1748 CreateFd("DumpFileOnDryRun.txt");
1749 SetDryRun(true);
1750 std::string path = kTestDataPath + "single-line.txt";
1751 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
1752 EXPECT_THAT(err, IsEmpty());
1753 EXPECT_THAT(out, StrEq(path + ": skipped on dry run\n"));
1754}
1755
Felipe Leme46b85da2016-11-21 17:40:45 -08001756TEST_F(DumpstateUtilTest, DumpFileOnDryRun) {
1757 CreateFd("DumpFileOnDryRun.txt");
1758 SetDryRun(true);
1759 std::string path = kTestDataPath + "single-line.txt";
Felipe Lemef0292972016-11-22 13:57:05 -08001760 EXPECT_EQ(0, DumpFile("Might as well dump. Dump!", kTestDataPath + "single-line.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001761 EXPECT_THAT(err, IsEmpty());
Felipe Lemef0292972016-11-22 13:57:05 -08001762 EXPECT_THAT(
1763 out, StartsWith("------ Might as well dump. Dump! (" + kTestDataPath + "single-line.txt:"));
1764 EXPECT_THAT(out, EndsWith("skipped on dry run\n"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001765}
Ecco Park61ffcf72016-10-27 15:46:26 -07001766
1767TEST_F(DumpstateUtilTest, FindingPidWithExistingProcess) {
1768 // init process always has pid 1.
1769 EXPECT_EQ(1, FindPidOfProcess("init"));
1770 EXPECT_THAT(err, IsEmpty());
1771}
1772
1773TEST_F(DumpstateUtilTest, FindingPidWithNotExistingProcess) {
1774 // find the process with abnormal name.
1775 EXPECT_EQ(-1, FindPidOfProcess("abcdef12345-543"));
1776 EXPECT_THAT(err, StrEq("can't find the pid\n"));
1777}
Felipe Leme47e9be22016-12-21 15:37:07 -08001778
1779} // namespace dumpstate
1780} // namespace os
1781} // namespace android