blob: e6a7735d60e4477b15f443d31b1c86a808d15c9d [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,
Felipe Leme7447d7c2016-11-03 18:12:22 -0700669 StartsWith("------ I AM GROOT (" + kSimpleCommand + ") ------\nstdout\n------"));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700670 EXPECT_THAT(out, EndsWith("s was the duration of 'I AM GROOT' ------\n"));
671}
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}));
Felipe Leme4c2d6632016-09-28 14:32:00 -0700703 // We don't know the exact duration, so we check the prefix and suffix
Felipe Leme7447d7c2016-11-03 18:12:22 -0700704 EXPECT_THAT(out, StartsWith("------ I AM GROOT (" + kSimpleCommand +
Felipe Leme4c2d6632016-09-28 14:32:00 -0700705 ") ------\n\t(skipped on dry run)\n------"));
706 EXPECT_THAT(out, EndsWith("s was the duration of 'I AM GROOT' ------\n"));
707 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());
1042 // We don't know the exact duration, so we check the prefix and suffix
1043 EXPECT_THAT(out, StartsWith("*** Error dumping /I/cant/believe/I/exist (Y U NO EXIST?): No "
1044 "such file or directory\n"));
1045 EXPECT_THAT(out, EndsWith("s was the duration of 'Y U NO EXIST?' ------\n"));
1046}
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:"));
1085 EXPECT_THAT(out, HasSubstr("\n\t(skipped on dry run)\n------"));
Felipe Lemecef02982016-10-03 17:22:22 -07001086 EXPECT_THAT(out, EndsWith("s was the duration of 'Might as well dump. Dump!' ------\n"));
Felipe Lemecef02982016-10-03 17:22:22 -07001087}
1088
Felipe Leme75876a22016-10-27 16:31:27 -07001089TEST_F(DumpstateTest, DumpFileUpdateProgress) {
1090 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
1091 ds.listener_ = listener;
1092 ds.listener_name_ = "FoxMulder";
Felipe Leme7447d7c2016-11-03 18:12:22 -07001093 SetProgress(0, 30);
Felipe Leme75876a22016-10-27 16:31:27 -07001094
1095 EXPECT_CALL(*listener, onProgressUpdated(5));
Nandana Duttbabf6c72019-01-15 14:11:12 +00001096 EXPECT_CALL(*listener, onProgress(16)); // 5/30 %
Felipe Leme7447d7c2016-11-03 18:12:22 -07001097 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
Felipe Leme75876a22016-10-27 16:31:27 -07001098
1099 std::string progress_message =
1100 GetProgressMessage(ds.listener_name_, 5, 30); // TODO: unhardcode WEIGHT_FILE (5)?
1101 EXPECT_THAT(err, StrEq(progress_message));
1102 EXPECT_THAT(out, StrEq("I AM LINE1\n")); // dumpstate adds missing newline
1103
1104 ds.listener_.clear();
1105}
1106
Felipe Leme7447d7c2016-11-03 18:12:22 -07001107class DumpstateServiceTest : public DumpstateBaseTest {
Felipe Leme75876a22016-10-27 16:31:27 -07001108 public:
1109 DumpstateService dss;
1110};
1111
1112TEST_F(DumpstateServiceTest, SetListenerNoName) {
1113 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
Felipe Leme009ecbb2016-11-07 10:18:44 -08001114 sp<IDumpstateToken> token;
Vishnu Nair20cf5032018-01-05 13:15:49 -08001115 EXPECT_TRUE(dss.setListener("", listener, /* getSectionDetails = */ false, &token).isOk());
Felipe Leme009ecbb2016-11-07 10:18:44 -08001116 ASSERT_THAT(token, IsNull());
Felipe Leme75876a22016-10-27 16:31:27 -07001117}
1118
1119TEST_F(DumpstateServiceTest, SetListenerNoPointer) {
Felipe Leme009ecbb2016-11-07 10:18:44 -08001120 sp<IDumpstateToken> token;
Vishnu Nair20cf5032018-01-05 13:15:49 -08001121 EXPECT_TRUE(
1122 dss.setListener("whatever", nullptr, /* getSectionDetails = */ false, &token).isOk());
Felipe Leme009ecbb2016-11-07 10:18:44 -08001123 ASSERT_THAT(token, IsNull());
Felipe Leme75876a22016-10-27 16:31:27 -07001124}
1125
1126TEST_F(DumpstateServiceTest, SetListenerTwice) {
1127 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
Felipe Leme009ecbb2016-11-07 10:18:44 -08001128 sp<IDumpstateToken> token;
Vishnu Nair20cf5032018-01-05 13:15:49 -08001129 EXPECT_TRUE(
1130 dss.setListener("whatever", listener, /* getSectionDetails = */ false, &token).isOk());
Felipe Leme009ecbb2016-11-07 10:18:44 -08001131 ASSERT_THAT(token, NotNull());
Felipe Leme75876a22016-10-27 16:31:27 -07001132 EXPECT_THAT(Dumpstate::GetInstance().listener_name_, StrEq("whatever"));
Vishnu Nair20cf5032018-01-05 13:15:49 -08001133 EXPECT_FALSE(Dumpstate::GetInstance().report_section_);
Felipe Leme75876a22016-10-27 16:31:27 -07001134
Felipe Leme009ecbb2016-11-07 10:18:44 -08001135 token.clear();
Vishnu Nair20cf5032018-01-05 13:15:49 -08001136 EXPECT_TRUE(
1137 dss.setListener("whatsoever", listener, /* getSectionDetails = */ false, &token).isOk());
Felipe Leme009ecbb2016-11-07 10:18:44 -08001138 ASSERT_THAT(token, IsNull());
1139 EXPECT_THAT(Dumpstate::GetInstance().listener_name_, StrEq("whatever"));
Vishnu Nair20cf5032018-01-05 13:15:49 -08001140 EXPECT_FALSE(Dumpstate::GetInstance().report_section_);
1141}
1142
1143TEST_F(DumpstateServiceTest, SetListenerWithSectionDetails) {
1144 sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
1145 sp<IDumpstateToken> token;
1146 Dumpstate::GetInstance().listener_ = nullptr;
1147 EXPECT_TRUE(
1148 dss.setListener("whatever", listener, /* getSectionDetails = */ true, &token).isOk());
1149 ASSERT_THAT(token, NotNull());
1150 EXPECT_THAT(Dumpstate::GetInstance().listener_name_, StrEq("whatever"));
1151 EXPECT_TRUE(Dumpstate::GetInstance().report_section_);
Felipe Leme75876a22016-10-27 16:31:27 -07001152}
Felipe Leme7447d7c2016-11-03 18:12:22 -07001153
1154class ProgressTest : public DumpstateBaseTest {
1155 public:
1156 Progress GetInstance(int32_t max, double growth_factor, const std::string& path = "") {
1157 return Progress(max, growth_factor, path);
1158 }
1159
1160 void AssertStats(const std::string& path, int32_t expected_runs, int32_t expected_average) {
1161 std::string expected_content =
1162 android::base::StringPrintf("%d %d\n", expected_runs, expected_average);
1163 std::string actual_content;
Felipe Leme46b85da2016-11-21 17:40:45 -08001164 ReadFileToString(path, &actual_content);
Felipe Leme7447d7c2016-11-03 18:12:22 -07001165 ASSERT_THAT(actual_content, StrEq(expected_content)) << "invalid stats on " << path;
1166 }
1167};
1168
1169TEST_F(ProgressTest, SimpleTest) {
1170 Progress progress;
1171 EXPECT_EQ(0, progress.Get());
1172 EXPECT_EQ(Progress::kDefaultMax, progress.GetInitialMax());
1173 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1174
1175 bool max_increased = progress.Inc(1);
1176 EXPECT_EQ(1, progress.Get());
1177 EXPECT_EQ(Progress::kDefaultMax, progress.GetInitialMax());
1178 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1179 EXPECT_FALSE(max_increased);
1180
1181 // Ignore negative increase.
1182 max_increased = progress.Inc(-1);
1183 EXPECT_EQ(1, progress.Get());
1184 EXPECT_EQ(Progress::kDefaultMax, progress.GetInitialMax());
1185 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1186 EXPECT_FALSE(max_increased);
1187}
1188
1189TEST_F(ProgressTest, MaxGrowsInsideNewRange) {
1190 Progress progress = GetInstance(10, 1.2); // 20% growth factor
1191 EXPECT_EQ(0, progress.Get());
1192 EXPECT_EQ(10, progress.GetInitialMax());
1193 EXPECT_EQ(10, progress.GetMax());
1194
1195 // No increase
1196 bool max_increased = progress.Inc(10);
1197 EXPECT_EQ(10, progress.Get());
1198 EXPECT_EQ(10, progress.GetMax());
1199 EXPECT_FALSE(max_increased);
1200
1201 // Increase, with new value < max*20%
1202 max_increased = progress.Inc(1);
1203 EXPECT_EQ(11, progress.Get());
1204 EXPECT_EQ(13, progress.GetMax()); // 11 average * 20% growth = 13.2 = 13
1205 EXPECT_TRUE(max_increased);
1206}
1207
1208TEST_F(ProgressTest, MaxGrowsOutsideNewRange) {
1209 Progress progress = GetInstance(10, 1.2); // 20% growth factor
1210 EXPECT_EQ(0, progress.Get());
1211 EXPECT_EQ(10, progress.GetInitialMax());
1212 EXPECT_EQ(10, progress.GetMax());
1213
1214 // No increase
1215 bool max_increased = progress.Inc(10);
1216 EXPECT_EQ(10, progress.Get());
1217 EXPECT_EQ(10, progress.GetMax());
1218 EXPECT_FALSE(max_increased);
1219
1220 // Increase, with new value > max*20%
1221 max_increased = progress.Inc(5);
1222 EXPECT_EQ(15, progress.Get());
1223 EXPECT_EQ(18, progress.GetMax()); // 15 average * 20% growth = 18
1224 EXPECT_TRUE(max_increased);
1225}
1226
1227TEST_F(ProgressTest, InvalidPath) {
1228 Progress progress("/devil/null");
1229 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1230}
1231
1232TEST_F(ProgressTest, EmptyFile) {
1233 Progress progress(CopyTextFileFixture("empty-file.txt"));
1234 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1235}
1236
1237TEST_F(ProgressTest, InvalidLine1stEntryNAN) {
1238 Progress progress(CopyTextFileFixture("stats-invalid-1st-NAN.txt"));
1239 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1240}
1241
1242TEST_F(ProgressTest, InvalidLine2ndEntryNAN) {
1243 Progress progress(CopyTextFileFixture("stats-invalid-2nd-NAN.txt"));
1244 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1245}
1246
1247TEST_F(ProgressTest, InvalidLineBothNAN) {
1248 Progress progress(CopyTextFileFixture("stats-invalid-both-NAN.txt"));
1249 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1250}
1251
1252TEST_F(ProgressTest, InvalidLine1stEntryNegative) {
1253 Progress progress(CopyTextFileFixture("stats-invalid-1st-negative.txt"));
1254 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1255}
1256
1257TEST_F(ProgressTest, InvalidLine2ndEntryNegative) {
1258 Progress progress(CopyTextFileFixture("stats-invalid-2nd-negative.txt"));
1259 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1260}
1261
1262TEST_F(ProgressTest, InvalidLine1stEntryTooBig) {
1263 Progress progress(CopyTextFileFixture("stats-invalid-1st-too-big.txt"));
1264 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1265}
1266
1267TEST_F(ProgressTest, InvalidLine2ndEntryTooBig) {
1268 Progress progress(CopyTextFileFixture("stats-invalid-2nd-too-big.txt"));
1269 EXPECT_EQ(Progress::kDefaultMax, progress.GetMax());
1270}
1271
1272// Tests stats are properly saved when the file does not exists.
1273TEST_F(ProgressTest, FirstTime) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001274 if (!IsStandalone()) {
1275 // TODO: temporarily disabled because it's failing when running as suite
1276 MYLOGE("Skipping ProgressTest.FirstTime() on test suite\n")
1277 return;
1278 }
1279
Felipe Leme7447d7c2016-11-03 18:12:22 -07001280 std::string path = kTestDataPath + "FirstTime.txt";
1281 android::base::RemoveFileIfExists(path);
1282
1283 Progress run1(path);
1284 EXPECT_EQ(0, run1.Get());
1285 EXPECT_EQ(Progress::kDefaultMax, run1.GetInitialMax());
1286 EXPECT_EQ(Progress::kDefaultMax, run1.GetMax());
1287
1288 bool max_increased = run1.Inc(20);
1289 EXPECT_EQ(20, run1.Get());
1290 EXPECT_EQ(Progress::kDefaultMax, run1.GetMax());
1291 EXPECT_FALSE(max_increased);
1292
1293 run1.Save();
1294 AssertStats(path, 1, 20);
1295}
1296
1297// Tests what happens when the persistent settings contains the average duration of 1 run.
1298// Data on file is 1 run and 109 average.
1299TEST_F(ProgressTest, SecondTime) {
1300 std::string path = CopyTextFileFixture("stats-one-run-no-newline.txt");
1301
1302 Progress run1 = GetInstance(-42, 1.2, path);
1303 EXPECT_EQ(0, run1.Get());
1304 EXPECT_EQ(10, run1.GetInitialMax());
1305 EXPECT_EQ(10, run1.GetMax());
1306
1307 bool max_increased = run1.Inc(20);
1308 EXPECT_EQ(20, run1.Get());
1309 EXPECT_EQ(24, run1.GetMax());
1310 EXPECT_TRUE(max_increased);
1311
1312 // Average now is 2 runs and (10 + 20)/ 2 = 15
1313 run1.Save();
1314 AssertStats(path, 2, 15);
1315
1316 Progress run2 = GetInstance(-42, 1.2, path);
1317 EXPECT_EQ(0, run2.Get());
1318 EXPECT_EQ(15, run2.GetInitialMax());
1319 EXPECT_EQ(15, run2.GetMax());
1320
1321 max_increased = run2.Inc(25);
1322 EXPECT_EQ(25, run2.Get());
1323 EXPECT_EQ(30, run2.GetMax());
1324 EXPECT_TRUE(max_increased);
1325
1326 // Average now is 3 runs and (15 * 2 + 25)/ 3 = 18.33 = 18
1327 run2.Save();
1328 AssertStats(path, 3, 18);
1329
1330 Progress run3 = GetInstance(-42, 1.2, path);
1331 EXPECT_EQ(0, run3.Get());
1332 EXPECT_EQ(18, run3.GetInitialMax());
1333 EXPECT_EQ(18, run3.GetMax());
1334
1335 // Make sure average decreases as well
1336 max_increased = run3.Inc(5);
1337 EXPECT_EQ(5, run3.Get());
1338 EXPECT_EQ(18, run3.GetMax());
1339 EXPECT_FALSE(max_increased);
1340
1341 // Average now is 4 runs and (18 * 3 + 5)/ 4 = 14.75 = 14
1342 run3.Save();
1343 AssertStats(path, 4, 14);
1344}
1345
1346// Tests what happens when the persistent settings contains the average duration of 2 runs.
1347// Data on file is 2 runs and 15 average.
1348TEST_F(ProgressTest, ThirdTime) {
1349 std::string path = CopyTextFileFixture("stats-two-runs.txt");
1350 AssertStats(path, 2, 15); // Sanity check
1351
1352 Progress run1 = GetInstance(-42, 1.2, path);
1353 EXPECT_EQ(0, run1.Get());
1354 EXPECT_EQ(15, run1.GetInitialMax());
1355 EXPECT_EQ(15, run1.GetMax());
1356
1357 bool max_increased = run1.Inc(20);
1358 EXPECT_EQ(20, run1.Get());
1359 EXPECT_EQ(24, run1.GetMax());
1360 EXPECT_TRUE(max_increased);
1361
1362 // Average now is 3 runs and (15 * 2 + 20)/ 3 = 16.66 = 16
1363 run1.Save();
1364 AssertStats(path, 3, 16);
1365}
1366
Felipe Leme46b85da2016-11-21 17:40:45 -08001367class DumpstateUtilTest : public DumpstateBaseTest {
1368 public:
1369 void SetUp() {
1370 DumpstateBaseTest::SetUp();
1371 SetDryRun(false);
1372 }
1373
Felipe Leme46b85da2016-11-21 17:40:45 -08001374 void CaptureFdOut() {
Felipe Lemef0292972016-11-22 13:57:05 -08001375 ReadFileToString(path_, &out);
Felipe Leme46b85da2016-11-21 17:40:45 -08001376 }
1377
1378 void CreateFd(const std::string& name) {
1379 path_ = kTestDataPath + name;
1380 MYLOGD("Creating fd for file %s\n", path_.c_str());
1381
1382 fd = TEMP_FAILURE_RETRY(open(path_.c_str(),
1383 O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW,
1384 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH));
1385 ASSERT_GE(fd, 0) << "could not create FD for path " << path_;
1386 }
1387
1388 // Runs a command into the `fd` and capture `stderr`.
Felipe Lemef0292972016-11-22 13:57:05 -08001389 int RunCommand(const std::string& title, const std::vector<std::string>& full_command,
Felipe Leme46b85da2016-11-21 17:40:45 -08001390 const CommandOptions& options = CommandOptions::DEFAULT) {
1391 CaptureStderr();
Felipe Lemef0292972016-11-22 13:57:05 -08001392 int status = RunCommandToFd(fd, title, full_command, options);
Felipe Leme46b85da2016-11-21 17:40:45 -08001393 close(fd);
1394
1395 CaptureFdOut();
1396 err = GetCapturedStderr();
1397 return status;
1398 }
1399
1400 // Dumps a file and into the `fd` and `stderr`.
Felipe Lemef0292972016-11-22 13:57:05 -08001401 int DumpFile(const std::string& title, const std::string& path) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001402 CaptureStderr();
Felipe Lemef0292972016-11-22 13:57:05 -08001403 int status = DumpFileToFd(fd, title, path);
Felipe Leme46b85da2016-11-21 17:40:45 -08001404 close(fd);
1405
1406 CaptureFdOut();
1407 err = GetCapturedStderr();
1408 return status;
1409 }
1410
Ecco Park61ffcf72016-10-27 15:46:26 -07001411 // Find out the pid of the process_name
1412 int FindPidOfProcess(const std::string& process_name) {
1413 CaptureStderr();
1414 int status = GetPidByName(process_name);
1415 err = GetCapturedStderr();
1416 return status;
1417 }
1418
Felipe Leme46b85da2016-11-21 17:40:45 -08001419 int fd;
1420
1421 // 'fd` output and `stderr` from the last command ran.
1422 std::string out, err;
1423
1424 private:
1425 std::string path_;
1426};
1427
1428TEST_F(DumpstateUtilTest, RunCommandNoArgs) {
Felipe Lemef0292972016-11-22 13:57:05 -08001429 CreateFd("RunCommandNoArgs.txt");
1430 EXPECT_EQ(-1, RunCommand("", {}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001431}
1432
Felipe Lemef0292972016-11-22 13:57:05 -08001433TEST_F(DumpstateUtilTest, RunCommandNoTitle) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001434 CreateFd("RunCommandWithNoArgs.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001435 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001436 EXPECT_THAT(out, StrEq("stdout\n"));
1437 EXPECT_THAT(err, StrEq("stderr\n"));
1438}
1439
Felipe Lemef0292972016-11-22 13:57:05 -08001440TEST_F(DumpstateUtilTest, RunCommandWithTitle) {
1441 CreateFd("RunCommandWithNoArgs.txt");
1442 EXPECT_EQ(0, RunCommand("I AM GROOT", {kSimpleCommand}));
1443 EXPECT_THAT(out, StrEq("------ I AM GROOT (" + kSimpleCommand + ") ------\nstdout\n"));
1444 EXPECT_THAT(err, StrEq("stderr\n"));
1445}
1446
Felipe Leme46b85da2016-11-21 17:40:45 -08001447TEST_F(DumpstateUtilTest, RunCommandWithOneArg) {
1448 CreateFd("RunCommandWithOneArg.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001449 EXPECT_EQ(0, RunCommand("", {kEchoCommand, "one"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001450 EXPECT_THAT(err, IsEmpty());
1451 EXPECT_THAT(out, StrEq("one\n"));
1452}
1453
1454TEST_F(DumpstateUtilTest, RunCommandWithMultipleArgs) {
1455 CreateFd("RunCommandWithMultipleArgs.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001456 EXPECT_EQ(0, RunCommand("", {kEchoCommand, "one", "is", "the", "loniest", "number"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001457 EXPECT_THAT(err, IsEmpty());
1458 EXPECT_THAT(out, StrEq("one is the loniest number\n"));
1459}
1460
1461TEST_F(DumpstateUtilTest, RunCommandWithLoggingMessage) {
1462 CreateFd("RunCommandWithLoggingMessage.txt");
1463 EXPECT_EQ(
Felipe Lemef0292972016-11-22 13:57:05 -08001464 0, RunCommand("", {kSimpleCommand},
Felipe Leme46b85da2016-11-21 17:40:45 -08001465 CommandOptions::WithTimeout(10).Log("COMMAND, Y U NO LOG FIRST?").Build()));
1466 EXPECT_THAT(out, StrEq("stdout\n"));
1467 EXPECT_THAT(err, StrEq("COMMAND, Y U NO LOG FIRST?stderr\n"));
1468}
1469
1470TEST_F(DumpstateUtilTest, RunCommandRedirectStderr) {
1471 CreateFd("RunCommandRedirectStderr.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001472 EXPECT_EQ(0, RunCommand("", {kSimpleCommand},
1473 CommandOptions::WithTimeout(10).RedirectStderr().Build()));
Felipe Leme46b85da2016-11-21 17:40:45 -08001474 EXPECT_THAT(out, IsEmpty());
1475 EXPECT_THAT(err, StrEq("stdout\nstderr\n"));
1476}
1477
1478TEST_F(DumpstateUtilTest, RunCommandDryRun) {
1479 CreateFd("RunCommandDryRun.txt");
1480 SetDryRun(true);
Felipe Lemef0292972016-11-22 13:57:05 -08001481 EXPECT_EQ(0, RunCommand("I AM GROOT", {kSimpleCommand}));
1482 EXPECT_THAT(out, StrEq(android::base::StringPrintf(
1483 "------ I AM GROOT (%s) ------\n\t(skipped on dry run)\n",
1484 kSimpleCommand.c_str())));
1485 EXPECT_THAT(err, IsEmpty());
1486}
1487
1488TEST_F(DumpstateUtilTest, RunCommandDryRunNoTitle) {
1489 CreateFd("RunCommandDryRun.txt");
1490 SetDryRun(true);
1491 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001492 EXPECT_THAT(
1493 out, StrEq(android::base::StringPrintf("%s: skipped on dry run\n", kSimpleCommand.c_str())));
1494 EXPECT_THAT(err, IsEmpty());
1495}
1496
1497TEST_F(DumpstateUtilTest, RunCommandDryRunAlways) {
1498 CreateFd("RunCommandDryRunAlways.txt");
1499 SetDryRun(true);
Felipe Lemef0292972016-11-22 13:57:05 -08001500 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(10).Always().Build()));
Felipe Leme46b85da2016-11-21 17:40:45 -08001501 EXPECT_THAT(out, StrEq("stdout\n"));
1502 EXPECT_THAT(err, StrEq("stderr\n"));
1503}
1504
1505TEST_F(DumpstateUtilTest, RunCommandNotFound) {
1506 CreateFd("RunCommandNotFound.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001507 EXPECT_NE(0, RunCommand("", {"/there/cannot/be/such/command"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001508 EXPECT_THAT(out, StartsWith("*** command '/there/cannot/be/such/command' failed: exit code"));
1509 EXPECT_THAT(err, StartsWith("execvp on command '/there/cannot/be/such/command' failed"));
1510}
1511
1512TEST_F(DumpstateUtilTest, RunCommandFails) {
1513 CreateFd("RunCommandFails.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001514 EXPECT_EQ(42, RunCommand("", {kSimpleCommand, "--exit", "42"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001515 EXPECT_THAT(out, StrEq("stdout\n*** command '" + kSimpleCommand +
1516 " --exit 42' failed: exit code 42\n"));
1517 EXPECT_THAT(err, StrEq("stderr\n*** command '" + kSimpleCommand +
1518 " --exit 42' failed: exit code 42\n"));
1519}
1520
1521TEST_F(DumpstateUtilTest, RunCommandCrashes) {
1522 CreateFd("RunCommandCrashes.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001523 EXPECT_NE(0, RunCommand("", {kSimpleCommand, "--crash"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001524 // We don't know the exit code, so check just the prefix.
1525 EXPECT_THAT(
1526 out, StartsWith("stdout\n*** command '" + kSimpleCommand + " --crash' failed: exit code"));
1527 EXPECT_THAT(
1528 err, StartsWith("stderr\n*** command '" + kSimpleCommand + " --crash' failed: exit code"));
1529}
1530
Vishnu Nair6921f802017-11-22 09:17:23 -08001531TEST_F(DumpstateUtilTest, RunCommandTimesoutWithSec) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001532 CreateFd("RunCommandTimesout.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001533 EXPECT_EQ(-1, RunCommand("", {kSimpleCommand, "--sleep", "2"},
1534 CommandOptions::WithTimeout(1).Build()));
Felipe Leme46b85da2016-11-21 17:40:45 -08001535 EXPECT_THAT(out, StartsWith("stdout line1\n*** command '" + kSimpleCommand +
1536 " --sleep 2' timed out after 1"));
1537 EXPECT_THAT(err, StartsWith("sleeping for 2s\n*** command '" + kSimpleCommand +
1538 " --sleep 2' timed out after 1"));
1539}
1540
Vishnu Nair6921f802017-11-22 09:17:23 -08001541TEST_F(DumpstateUtilTest, RunCommandTimesoutWithMsec) {
1542 CreateFd("RunCommandTimesout.txt");
1543 EXPECT_EQ(-1, RunCommand("", {kSimpleCommand, "--sleep", "2"},
1544 CommandOptions::WithTimeoutInMs(1000).Build()));
1545 EXPECT_THAT(out, StartsWith("stdout line1\n*** command '" + kSimpleCommand +
1546 " --sleep 2' timed out after 1"));
1547 EXPECT_THAT(err, StartsWith("sleeping for 2s\n*** command '" + kSimpleCommand +
1548 " --sleep 2' timed out after 1"));
1549}
1550
1551
Felipe Leme46b85da2016-11-21 17:40:45 -08001552TEST_F(DumpstateUtilTest, RunCommandIsKilled) {
1553 CreateFd("RunCommandIsKilled.txt");
1554 CaptureStderr();
1555
1556 std::thread t([=]() {
Felipe Lemef0292972016-11-22 13:57:05 -08001557 EXPECT_EQ(SIGTERM, RunCommandToFd(fd, "", {kSimpleCommand, "--pid", "--sleep", "20"},
Felipe Leme46b85da2016-11-21 17:40:45 -08001558 CommandOptions::WithTimeout(100).Always().Build()));
1559 });
1560
1561 // Capture pid and pre-sleep output.
1562 sleep(1); // Wait a little bit to make sure pid and 1st line were printed.
1563 std::string err = GetCapturedStderr();
1564 EXPECT_THAT(err, StrEq("sleeping for 20s\n"));
1565
1566 CaptureFdOut();
1567 std::vector<std::string> lines = android::base::Split(out, "\n");
1568 ASSERT_EQ(3, (int)lines.size()) << "Invalid lines before sleep: " << out;
1569
1570 int pid = atoi(lines[0].c_str());
1571 EXPECT_THAT(lines[1], StrEq("stdout line1"));
1572 EXPECT_THAT(lines[2], IsEmpty()); // \n
1573
1574 // Then kill the process.
1575 CaptureFdOut();
1576 CaptureStderr();
1577 ASSERT_EQ(0, kill(pid, SIGTERM)) << "failed to kill pid " << pid;
1578 t.join();
1579
1580 // Finally, check output after murder.
1581 CaptureFdOut();
1582 err = GetCapturedStderr();
1583
1584 // out starts with the pid, which is an unknown
1585 EXPECT_THAT(out, EndsWith("stdout line1\n*** command '" + kSimpleCommand +
1586 " --pid --sleep 20' failed: killed by signal 15\n"));
1587 EXPECT_THAT(err, StrEq("*** command '" + kSimpleCommand +
1588 " --pid --sleep 20' failed: killed by signal 15\n"));
1589}
1590
1591TEST_F(DumpstateUtilTest, RunCommandAsRootUserBuild) {
1592 if (!IsStandalone()) {
1593 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1594 // to Shell - need to refactor tests to avoid this problem)
1595 MYLOGE("Skipping DumpstateUtilTest.RunCommandAsRootUserBuild() on test suite\n")
1596 return;
1597 }
1598 CreateFd("RunCommandAsRootUserBuild.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001599 if (!PropertiesHelper::IsUserBuild()) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001600 // Emulates user build if necessarily.
1601 SetBuildType("user");
1602 }
1603
1604 DropRoot();
1605
Felipe Lemef0292972016-11-22 13:57:05 -08001606 EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).AsRoot().Build()));
Felipe Leme46b85da2016-11-21 17:40:45 -08001607
1608 // We don't know the exact path of su, so we just check for the 'root ...' commands
1609 EXPECT_THAT(out, StartsWith("Skipping"));
1610 EXPECT_THAT(out, EndsWith("root " + kSimpleCommand + "' on user build.\n"));
1611 EXPECT_THAT(err, IsEmpty());
1612}
1613
1614TEST_F(DumpstateUtilTest, RunCommandAsRootNonUserBuild) {
1615 if (!IsStandalone()) {
1616 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1617 // to Shell - need to refactor tests to avoid this problem)
1618 MYLOGE("Skipping DumpstateUtilTest.RunCommandAsRootNonUserBuild() on test suite\n")
1619 return;
1620 }
1621 CreateFd("RunCommandAsRootNonUserBuild.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001622 if (PropertiesHelper::IsUserBuild()) {
Felipe Leme7447d7c2016-11-03 18:12:22 -07001623 ALOGI("Skipping RunCommandAsRootNonUserBuild on user builds\n");
1624 return;
1625 }
1626
1627 DropRoot();
1628
Felipe Lemef0292972016-11-22 13:57:05 -08001629 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
1630 CommandOptions::WithTimeout(1).AsRoot().Build()));
Felipe Leme7447d7c2016-11-03 18:12:22 -07001631
1632 EXPECT_THAT(out, StrEq("0\nstdout\n"));
1633 EXPECT_THAT(err, StrEq("stderr\n"));
1634}
Felipe Leme46b85da2016-11-21 17:40:45 -08001635
Yifan Hong48e83a12017-10-03 14:10:07 -07001636
1637TEST_F(DumpstateUtilTest, RunCommandAsRootIfAvailableOnUserBuild) {
1638 if (!IsStandalone()) {
1639 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1640 // to Shell - need to refactor tests to avoid this problem)
1641 MYLOGE("Skipping DumpstateUtilTest.RunCommandAsRootIfAvailableOnUserBuild() on test suite\n")
1642 return;
1643 }
1644 CreateFd("RunCommandAsRootIfAvailableOnUserBuild.txt");
1645 if (!PropertiesHelper::IsUserBuild()) {
1646 // Emulates user build if necessarily.
1647 SetBuildType("user");
1648 }
1649
1650 DropRoot();
1651
1652 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
1653 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
1654
1655 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
1656 EXPECT_THAT(err, StrEq("stderr\n"));
1657}
1658
1659TEST_F(DumpstateUtilTest, RunCommandAsRootIfAvailableOnDebugBuild) {
1660 if (!IsStandalone()) {
1661 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1662 // to Shell - need to refactor tests to avoid this problem)
1663 MYLOGE("Skipping DumpstateUtilTest.RunCommandAsRootIfAvailableOnDebugBuild() on test suite\n")
1664 return;
1665 }
1666 CreateFd("RunCommandAsRootIfAvailableOnDebugBuild.txt");
1667 if (PropertiesHelper::IsUserBuild()) {
1668 ALOGI("Skipping RunCommandAsRootNonUserBuild on user builds\n");
1669 return;
1670 }
1671
1672 DropRoot();
1673
1674 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
1675 CommandOptions::WithTimeout(1).AsRootIfAvailable().Build()));
1676
1677 EXPECT_THAT(out, StrEq("0\nstdout\n"));
1678 EXPECT_THAT(err, StrEq("stderr\n"));
1679}
1680
Felipe Leme46b85da2016-11-21 17:40:45 -08001681TEST_F(DumpstateUtilTest, RunCommandDropRoot) {
1682 if (!IsStandalone()) {
1683 // TODO: temporarily disabled because it might cause other tests to fail after dropping
1684 // to Shell - need to refactor tests to avoid this problem)
1685 MYLOGE("Skipping DumpstateUtilTest.RunCommandDropRoot() on test suite\n")
1686 return;
1687 }
1688 CreateFd("RunCommandDropRoot.txt");
1689 // First check root case - only available when running with 'adb root'.
1690 uid_t uid = getuid();
1691 if (uid == 0) {
Felipe Lemef0292972016-11-22 13:57:05 -08001692 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"}));
Felipe Leme46b85da2016-11-21 17:40:45 -08001693 EXPECT_THAT(out, StrEq("0\nstdout\n"));
1694 EXPECT_THAT(err, StrEq("stderr\n"));
1695 return;
1696 }
1697 // Then run dropping root.
Felipe Lemef0292972016-11-22 13:57:05 -08001698 EXPECT_EQ(0, RunCommand("", {kSimpleCommand, "--uid"},
Felipe Leme46b85da2016-11-21 17:40:45 -08001699 CommandOptions::WithTimeout(1).DropRoot().Build()));
1700 EXPECT_THAT(out, StrEq("2000\nstdout\n"));
1701 EXPECT_THAT(err, StrEq("drop_root_user(): already running as Shell\nstderr\n"));
1702}
1703
Felipe Lemef0292972016-11-22 13:57:05 -08001704TEST_F(DumpstateUtilTest, DumpFileNotFoundNoTitle) {
Felipe Leme46b85da2016-11-21 17:40:45 -08001705 CreateFd("DumpFileNotFound.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001706 EXPECT_EQ(-1, DumpFile("", "/I/cant/believe/I/exist"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001707 EXPECT_THAT(out,
1708 StrEq("*** Error dumping /I/cant/believe/I/exist: No such file or directory\n"));
1709 EXPECT_THAT(err, IsEmpty());
1710}
1711
Felipe Lemef0292972016-11-22 13:57:05 -08001712TEST_F(DumpstateUtilTest, DumpFileNotFoundWithTitle) {
1713 CreateFd("DumpFileNotFound.txt");
1714 EXPECT_EQ(-1, DumpFile("Y U NO EXIST?", "/I/cant/believe/I/exist"));
1715 EXPECT_THAT(out, StrEq("*** Error dumping /I/cant/believe/I/exist (Y U NO EXIST?): No such "
1716 "file or directory\n"));
1717 EXPECT_THAT(err, IsEmpty());
1718}
1719
Felipe Leme46b85da2016-11-21 17:40:45 -08001720TEST_F(DumpstateUtilTest, DumpFileSingleLine) {
1721 CreateFd("DumpFileSingleLine.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001722 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001723 EXPECT_THAT(err, IsEmpty());
1724 EXPECT_THAT(out, StrEq("I AM LINE1\n")); // dumpstate adds missing newline
1725}
1726
1727TEST_F(DumpstateUtilTest, DumpFileSingleLineWithNewLine) {
1728 CreateFd("DumpFileSingleLineWithNewLine.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001729 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line-with-newline.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001730 EXPECT_THAT(err, IsEmpty());
1731 EXPECT_THAT(out, StrEq("I AM LINE1\n"));
1732}
1733
1734TEST_F(DumpstateUtilTest, DumpFileMultipleLines) {
1735 CreateFd("DumpFileMultipleLines.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001736 EXPECT_EQ(0, DumpFile("", kTestDataPath + "multiple-lines.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001737 EXPECT_THAT(err, IsEmpty());
1738 EXPECT_THAT(out, StrEq("I AM LINE1\nI AM LINE2\nI AM LINE3\n"));
1739}
1740
1741TEST_F(DumpstateUtilTest, DumpFileMultipleLinesWithNewLine) {
1742 CreateFd("DumpFileMultipleLinesWithNewLine.txt");
Felipe Lemef0292972016-11-22 13:57:05 -08001743 EXPECT_EQ(0, DumpFile("", kTestDataPath + "multiple-lines-with-newline.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001744 EXPECT_THAT(err, IsEmpty());
1745 EXPECT_THAT(out, StrEq("I AM LINE1\nI AM LINE2\nI AM LINE3\n"));
1746}
1747
Felipe Lemef0292972016-11-22 13:57:05 -08001748TEST_F(DumpstateUtilTest, DumpFileOnDryRunNoTitle) {
1749 CreateFd("DumpFileOnDryRun.txt");
1750 SetDryRun(true);
1751 std::string path = kTestDataPath + "single-line.txt";
1752 EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
1753 EXPECT_THAT(err, IsEmpty());
1754 EXPECT_THAT(out, StrEq(path + ": skipped on dry run\n"));
1755}
1756
Felipe Leme46b85da2016-11-21 17:40:45 -08001757TEST_F(DumpstateUtilTest, DumpFileOnDryRun) {
1758 CreateFd("DumpFileOnDryRun.txt");
1759 SetDryRun(true);
1760 std::string path = kTestDataPath + "single-line.txt";
Felipe Lemef0292972016-11-22 13:57:05 -08001761 EXPECT_EQ(0, DumpFile("Might as well dump. Dump!", kTestDataPath + "single-line.txt"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001762 EXPECT_THAT(err, IsEmpty());
Felipe Lemef0292972016-11-22 13:57:05 -08001763 EXPECT_THAT(
1764 out, StartsWith("------ Might as well dump. Dump! (" + kTestDataPath + "single-line.txt:"));
1765 EXPECT_THAT(out, EndsWith("skipped on dry run\n"));
Felipe Leme46b85da2016-11-21 17:40:45 -08001766}
Ecco Park61ffcf72016-10-27 15:46:26 -07001767
1768TEST_F(DumpstateUtilTest, FindingPidWithExistingProcess) {
1769 // init process always has pid 1.
1770 EXPECT_EQ(1, FindPidOfProcess("init"));
1771 EXPECT_THAT(err, IsEmpty());
1772}
1773
1774TEST_F(DumpstateUtilTest, FindingPidWithNotExistingProcess) {
1775 // find the process with abnormal name.
1776 EXPECT_EQ(-1, FindPidOfProcess("abcdef12345-543"));
1777 EXPECT_THAT(err, StrEq("can't find the pid\n"));
1778}
Felipe Leme47e9be22016-12-21 15:37:07 -08001779
1780} // namespace dumpstate
1781} // namespace os
1782} // namespace android