| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package org.chromium.chrome.browser.crash; | 5 package org.chromium.chrome.browser.crash; |
| 6 | 6 |
| 7 import static org.chromium.chrome.browser.crash.MinidumpUploadService.BROWSER; | 7 import static org.chromium.chrome.browser.crash.MinidumpUploadService.BROWSER; |
| 8 import static org.chromium.chrome.browser.crash.MinidumpUploadService.GPU; | 8 import static org.chromium.chrome.browser.crash.MinidumpUploadService.GPU; |
| 9 import static org.chromium.chrome.browser.crash.MinidumpUploadService.OTHER; | 9 import static org.chromium.chrome.browser.crash.MinidumpUploadService.OTHER; |
| 10 import static org.chromium.chrome.browser.crash.MinidumpUploadService.RENDERER; | 10 import static org.chromium.chrome.browser.crash.MinidumpUploadService.RENDERER; |
| 11 | 11 |
| 12 import android.annotation.TargetApi; |
| 13 import android.app.job.JobInfo; |
| 14 import android.app.job.JobScheduler; |
| 12 import android.content.ComponentName; | 15 import android.content.ComponentName; |
| 13 import android.content.Context; | 16 import android.content.Context; |
| 14 import android.content.Intent; | 17 import android.content.Intent; |
| 18 import android.os.Build; |
| 15 import android.os.Handler; | 19 import android.os.Handler; |
| 16 import android.os.HandlerThread; | 20 import android.os.HandlerThread; |
| 17 import android.support.test.filters.SmallTest; | 21 import android.support.test.filters.SmallTest; |
| 18 | 22 |
| 19 import org.chromium.base.annotations.SuppressFBWarnings; | 23 import org.chromium.base.annotations.SuppressFBWarnings; |
| 20 import org.chromium.base.test.util.AdvancedMockContext; | 24 import org.chromium.base.test.util.AdvancedMockContext; |
| 21 import org.chromium.base.test.util.Feature; | 25 import org.chromium.base.test.util.Feature; |
| 26 import org.chromium.chrome.browser.ChromeFeatureList; |
| 27 import org.chromium.components.background_task_scheduler.TaskIds; |
| 22 import org.chromium.components.minidump_uploader.CrashTestCase; | 28 import org.chromium.components.minidump_uploader.CrashTestCase; |
| 23 import org.chromium.components.minidump_uploader.MinidumpUploadCallable; | 29 import org.chromium.components.minidump_uploader.MinidumpUploadCallable; |
| 24 import org.chromium.components.minidump_uploader.util.CrashReportingPermissionMa
nager; | 30 import org.chromium.components.minidump_uploader.util.CrashReportingPermissionMa
nager; |
| 25 import org.chromium.content.browser.test.util.Criteria; | 31 import org.chromium.content.browser.test.util.Criteria; |
| 26 import org.chromium.content.browser.test.util.CriteriaHelper; | 32 import org.chromium.content.browser.test.util.CriteriaHelper; |
| 27 import org.chromium.net.NetworkChangeNotifier; | 33 import org.chromium.net.NetworkChangeNotifier; |
| 28 | 34 |
| 29 import java.io.File; | 35 import java.io.File; |
| 30 import java.io.IOException; | 36 import java.io.IOException; |
| 31 import java.util.ArrayList; | 37 import java.util.ArrayList; |
| 38 import java.util.HashMap; |
| 32 import java.util.List; | 39 import java.util.List; |
| 40 import java.util.Map; |
| 33 import java.util.concurrent.atomic.AtomicInteger; | 41 import java.util.concurrent.atomic.AtomicInteger; |
| 34 /** | 42 /** |
| 35 * Testcase for {@link MinidumpUploadService}. | 43 * Testcase for {@link MinidumpUploadService}. |
| 36 */ | 44 */ |
| 37 public class MinidumpUploadServiceTest extends CrashTestCase { | 45 public class MinidumpUploadServiceTest extends CrashTestCase { |
| 38 private static final int CHECK_INTERVAL_MS = 250; | 46 private static final int CHECK_INTERVAL_MS = 250; |
| 39 private static final int MAX_TIMEOUT_MS = 20000; | 47 private static final int MAX_TIMEOUT_MS = 20000; |
| 40 private static final String BOUNDARY = "TESTBOUNDARY"; | 48 private static final String BOUNDARY = "TESTBOUNDARY"; |
| 41 | 49 |
| 42 private static class TestMinidumpUploadService extends MinidumpUploadService
{ | 50 private static class TestMinidumpUploadService extends MinidumpUploadService
{ |
| (...skipping 21 matching lines...) Expand all Loading... |
| 64 | 72 |
| 65 CrashReportingPermissionManager getCrashReportingPermissionManager() { | 73 CrashReportingPermissionManager getCrashReportingPermissionManager() { |
| 66 return mPermissionManager; | 74 return mPermissionManager; |
| 67 } | 75 } |
| 68 | 76 |
| 69 public void setIsNetworkAvailableForCrashUploads(boolean networkAvailabl
e) { | 77 public void setIsNetworkAvailableForCrashUploads(boolean networkAvailabl
e) { |
| 70 mPermissionManager.setIsNetworkAvailableForCrashUploads(networkAvail
able); | 78 mPermissionManager.setIsNetworkAvailableForCrashUploads(networkAvail
able); |
| 71 } | 79 } |
| 72 } | 80 } |
| 73 | 81 |
| 82 @Override |
| 83 protected void tearDown() throws Exception { |
| 84 ChromeFeatureList.setTestFeatures(null); |
| 85 super.tearDown(); |
| 86 } |
| 87 |
| 88 /** |
| 89 * Sets whether to upload minidumps using the JobScheduler API. Minidumps ca
n either be uploaded |
| 90 * via a JobScheduler, or via a direct Intent service. |
| 91 * @param enable Whether to enable the JobScheduler API. |
| 92 */ |
| 93 private void setJobSchedulerEnabled(boolean enable) { |
| 94 Map<String, Boolean> features = new HashMap<>(); |
| 95 features.put(ChromeFeatureList.UPLOAD_CRASH_REPORTS_USING_JOB_SCHEDULER,
enable); |
| 96 ChromeFeatureList.setTestFeatures(features); |
| 97 } |
| 98 |
| 74 @SmallTest | 99 @SmallTest |
| 75 @Feature({"Android-AppBase"}) | 100 @Feature({"Android-AppBase"}) |
| 76 public void testTryUploadAllCrashDumps() throws IOException { | 101 public void testTryUploadAllCrashDumps() throws IOException { |
| 77 // Setup prerequisites. | 102 // Setup prerequisites. |
| 103 setJobSchedulerEnabled(false); |
| 78 final AtomicInteger numServiceStarts = new AtomicInteger(0); | 104 final AtomicInteger numServiceStarts = new AtomicInteger(0); |
| 79 final File[] minidumpFiles = { | 105 final File[] minidumpFiles = { |
| 80 new File(mCrashDir, "chromium_renderer-111.dmp1"), | 106 new File(mCrashDir, "chromium_renderer-111.dmp1"), |
| 81 new File(mCrashDir, "chromium_renderer-222.dmp2"), | 107 new File(mCrashDir, "chromium_renderer-222.dmp2"), |
| 82 new File(mCrashDir, "chromium_renderer-333.dmp3"), | 108 new File(mCrashDir, "chromium_renderer-333.dmp3"), |
| 83 }; | 109 }; |
| 84 MinidumpPreparationContext context = new MinidumpPreparationContext( | 110 MinidumpPreparationContext context = new MinidumpPreparationContext( |
| 85 getInstrumentation().getTargetContext()) { | 111 getInstrumentation().getTargetContext()) { |
| 86 @Override | 112 @Override |
| 87 public ComponentName startService(Intent intentToCheck) { | 113 public ComponentName startService(Intent intentToCheck) { |
| 88 String filePath = | 114 String filePath = |
| 89 intentToCheck.getStringExtra(MinidumpUploadService.FILE_
TO_UPLOAD_KEY); | 115 intentToCheck.getStringExtra(MinidumpUploadService.FILE_
TO_UPLOAD_KEY); |
| 90 // Assuming numServicesStart value corresponds to minidumpFiles
index. | 116 // Assuming numServicesStart value corresponds to minidumpFiles
index. |
| 91 assertEquals("Minidump path should be the absolute path", | 117 assertEquals("Action should be correct", MinidumpUploadService.A
CTION_UPLOAD, |
| 92 minidumpFiles[numServiceStarts.intValue()].getAbsolutePa
th(), filePath); | 118 intentToCheck.getAction()); |
| 93 assertTrue("Should not call service more than number of files", | 119 assertTrue("Should not call service more than number of files", |
| 94 numServiceStarts.incrementAndGet() <= minidumpFiles.leng
th); | 120 numServiceStarts.incrementAndGet() <= minidumpFiles.leng
th); |
| 95 assertEquals("Action should be correct", MinidumpUploadService.A
CTION_UPLOAD, | 121 assertEquals("Minidump path should be the absolute path", |
| 96 intentToCheck.getAction()); | 122 minidumpFiles[numServiceStarts.intValue() - 1].getAbsolu
tePath(), filePath); |
| 97 return new ComponentName(getPackageName(), MinidumpUploadService
.class.getName()); | 123 return new ComponentName(getPackageName(), MinidumpUploadService
.class.getName()); |
| 98 } | 124 } |
| 99 | 125 |
| 100 }; | 126 }; |
| 101 MinidumpUploadService service = new TestMinidumpUploadService(context); | 127 MinidumpUploadService service = new TestMinidumpUploadService(context); |
| 102 for (File minidumpFile : minidumpFiles) { | 128 for (File minidumpFile : minidumpFiles) { |
| 103 setUpMinidumpFile(minidumpFile, BOUNDARY); | 129 setUpMinidumpFile(minidumpFile, BOUNDARY); |
| 104 } | 130 } |
| 105 | 131 |
| 106 // Run test. | 132 // Run test. |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 161 runUploadCrashTest(callables); | 187 runUploadCrashTest(callables); |
| 162 } | 188 } |
| 163 | 189 |
| 164 @SuppressFBWarnings("RV_RETURN_VALUE_IGNORED_BAD_PRACTICE") | 190 @SuppressFBWarnings("RV_RETURN_VALUE_IGNORED_BAD_PRACTICE") |
| 165 private void runUploadCrashTest(final List<CountedMinidumpUploadCallable> ca
llables) | 191 private void runUploadCrashTest(final List<CountedMinidumpUploadCallable> ca
llables) |
| 166 throws IOException, InterruptedException { | 192 throws IOException, InterruptedException { |
| 167 // Setup prerequisites. | 193 // Setup prerequisites. |
| 168 // This version of the service overrides the createMinidumpUploadCallabl
e(...) to be able | 194 // This version of the service overrides the createMinidumpUploadCallabl
e(...) to be able |
| 169 // to return fake ones. It also ensures that the service never tries to
create a callable | 195 // to return fake ones. It also ensures that the service never tries to
create a callable |
| 170 // too many times. | 196 // too many times. |
| 197 setJobSchedulerEnabled(false); |
| 171 TestMinidumpUploadService service = new TestMinidumpUploadService() { | 198 TestMinidumpUploadService service = new TestMinidumpUploadService() { |
| 172 int mIndex = 0; | 199 int mIndex = 0; |
| 173 boolean mTriggerNetworkChange = false; | 200 boolean mTriggerNetworkChange = false; |
| 174 | 201 |
| 175 @Override | 202 @Override |
| 176 MinidumpUploadCallable createMinidumpUploadCallable(File minidumpFil
e, File logfile) { | 203 MinidumpUploadCallable createMinidumpUploadCallable(File minidumpFil
e, File logfile) { |
| 177 if (mIndex >= callables.size()) { | 204 if (mIndex >= callables.size()) { |
| 178 fail("Should not create callable number " + mIndex); | 205 fail("Should not create callable number " + mIndex); |
| 179 } | 206 } |
| 180 CountedMinidumpUploadCallable callable = callables.get(mIndex++)
; | 207 CountedMinidumpUploadCallable callable = callables.get(mIndex++)
; |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 275 } | 302 } |
| 276 } | 303 } |
| 277 return true; | 304 return true; |
| 278 } | 305 } |
| 279 }, | 306 }, |
| 280 MAX_TIMEOUT_MS, CHECK_INTERVAL_MS); | 307 MAX_TIMEOUT_MS, CHECK_INTERVAL_MS); |
| 281 } | 308 } |
| 282 | 309 |
| 283 @SmallTest | 310 @SmallTest |
| 284 @Feature({"Android-AppBase"}) | 311 @Feature({"Android-AppBase"}) |
| 285 public void testHandleForceUploadCrash_MinidumpFileExists() throws IOExcepti
on { | 312 public void testHandleForceUploadCrash_MinidumpFileExists_SansJobScheduler() |
| 313 throws IOException { |
| 286 // Set up prerequisites. | 314 // Set up prerequisites. |
| 315 setJobSchedulerEnabled(false); |
| 287 File minidumpFile = | 316 File minidumpFile = |
| 288 new File(mCrashDir, "chromium-renderer-minidump-f297dbcba7a2d0bb
.dmp0.try3"); | 317 new File(mCrashDir, "chromium-renderer-minidump-f297dbcba7a2d0bb
.dmp0.try3"); |
| 289 final File expectedRenamedMinidumpFile = | 318 final File expectedRenamedMinidumpFile = |
| 290 new File(mCrashDir, "chromium-renderer-minidump-f297dbcba7a2d0bb
.forced0.try0"); | 319 new File(mCrashDir, "chromium-renderer-minidump-f297dbcba7a2d0bb
.forced0.try0"); |
| 291 setUpMinidumpFile(minidumpFile, BOUNDARY); | 320 setUpMinidumpFile(minidumpFile, BOUNDARY); |
| 292 final String startServiceFlag = "startServiceFlag"; | 321 final String startServiceFlag = "startServiceFlag"; |
| 293 MinidumpPreparationContext context = new MinidumpPreparationContext( | 322 MinidumpPreparationContext context = new MinidumpPreparationContext( |
| 294 getInstrumentation().getTargetContext()) { | 323 getInstrumentation().getTargetContext()) { |
| 295 @Override | 324 @Override |
| 296 public ComponentName startService(Intent intentToCheck) { | 325 public ComponentName startService(Intent intentToCheck) { |
| 297 assertEquals(MinidumpUploadService.ACTION_UPLOAD, intentToCheck.
getAction()); | 326 assertEquals(MinidumpUploadService.ACTION_UPLOAD, intentToCheck.
getAction()); |
| 298 String filePath = | 327 String filePath = |
| 299 intentToCheck.getStringExtra(MinidumpUploadService.FILE_
TO_UPLOAD_KEY); | 328 intentToCheck.getStringExtra(MinidumpUploadService.FILE_
TO_UPLOAD_KEY); |
| 300 assertEquals("Minidump path should be for a fresh upload", | 329 assertEquals("Minidump path should be for a fresh upload", |
| 301 expectedRenamedMinidumpFile.getAbsolutePath(), filePath)
; | 330 expectedRenamedMinidumpFile.getAbsolutePath(), filePath)
; |
| 302 setFlag(startServiceFlag); | 331 setFlag(startServiceFlag); |
| 303 return new ComponentName(getPackageName(), MinidumpUploadService
.class.getName()); | 332 return new ComponentName(getPackageName(), MinidumpUploadService
.class.getName()); |
| 304 } | 333 } |
| 305 }; | 334 }; |
| 306 | 335 |
| 307 // Run test. | 336 // Run test. |
| 308 MinidumpUploadService.tryUploadCrashDumpWithLocalId(context, "f297dbcba7
a2d0bb"); | 337 MinidumpUploadService.tryUploadCrashDumpWithLocalId(context, "f297dbcba7
a2d0bb"); |
| 309 | 338 |
| 310 // Verify. | 339 // Verify. |
| 311 assertTrue("Should have called startService(...)", context.isFlagSet(sta
rtServiceFlag)); | 340 assertTrue("Should have called startService(...)", context.isFlagSet(sta
rtServiceFlag)); |
| 312 } | 341 } |
| 313 | 342 |
| 314 @SmallTest | 343 @SmallTest |
| 315 @Feature({"Android-AppBase"}) | 344 @Feature({"Android-AppBase"}) |
| 316 public void testHandleForceUploadCrash_SkippedMinidumpFileExists() throws IO
Exception { | 345 public void testHandleForceUploadCrash_MinidumpFileExists_WithJobScheduler() |
| 346 throws IOException { |
| 347 // The JobScheduler API is only available as of Android M. |
| 348 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return; |
| 349 setJobSchedulerEnabled(true); |
| 350 |
| 317 // Set up prerequisites. | 351 // Set up prerequisites. |
| 352 setUpMinidumpFile( |
| 353 new File(mCrashDir, "chromium-renderer-minidump-f297dbcba7a2d0bb
.dmp0.try3"), |
| 354 BOUNDARY); |
| 355 AdvancedMockContext context = |
| 356 new MinidumpPreparationContext(getInstrumentation().getTargetCon
text()); |
| 357 |
| 358 // Run test. |
| 359 MinidumpUploadService.tryUploadCrashDumpWithLocalId(context, "f297dbcba7
a2d0bb"); |
| 360 |
| 361 // Verify. |
| 362 final File expectedRenamedMinidumpFile = |
| 363 new File(mCrashDir, "chromium-renderer-minidump-f297dbcba7a2d0bb
.forced0.try0"); |
| 364 assertTrue("Should have renamed the minidump file for forced upload", |
| 365 expectedRenamedMinidumpFile.exists()); |
| 366 assertTrue("Should have tried to schedule an upload job", |
| 367 context.isFlagSet(TestJobScheduler.SCHEDULE_JOB_FLAG)); |
| 368 } |
| 369 |
| 370 @SmallTest |
| 371 @Feature({"Android-AppBase"}) |
| 372 public void testHandleForceUploadCrash_SkippedMinidumpFileExists_SansJobSche
duler() |
| 373 throws IOException { |
| 374 // Set up prerequisites. |
| 375 setJobSchedulerEnabled(false); |
| 318 File minidumpFile = | 376 File minidumpFile = |
| 319 new File(mCrashDir, "chromium-renderer-minidump-f297dbcba7a2d0bb
.skipped0.try0"); | 377 new File(mCrashDir, "chromium-renderer-minidump-f297dbcba7a2d0bb
.skipped0.try0"); |
| 320 final File expectedRenamedMinidumpFile = | 378 final File expectedRenamedMinidumpFile = |
| 321 new File(mCrashDir, "chromium-renderer-minidump-f297dbcba7a2d0bb
.forced0.try0"); | 379 new File(mCrashDir, "chromium-renderer-minidump-f297dbcba7a2d0bb
.forced0.try0"); |
| 322 setUpMinidumpFile(minidumpFile, BOUNDARY); | 380 setUpMinidumpFile(minidumpFile, BOUNDARY); |
| 323 final String startServiceFlag = "startServiceFlag"; | 381 final String startServiceFlag = "startServiceFlag"; |
| 324 MinidumpPreparationContext context = new MinidumpPreparationContext( | 382 MinidumpPreparationContext context = new MinidumpPreparationContext( |
| 325 getInstrumentation().getTargetContext()) { | 383 getInstrumentation().getTargetContext()) { |
| 326 @Override | 384 @Override |
| 327 public ComponentName startService(Intent intentToCheck) { | 385 public ComponentName startService(Intent intentToCheck) { |
| 328 assertEquals(MinidumpUploadService.ACTION_UPLOAD, intentToCheck.
getAction()); | 386 assertEquals(MinidumpUploadService.ACTION_UPLOAD, intentToCheck.
getAction()); |
| 329 String filePath = | 387 String filePath = |
| 330 intentToCheck.getStringExtra(MinidumpUploadService.FILE_
TO_UPLOAD_KEY); | 388 intentToCheck.getStringExtra(MinidumpUploadService.FILE_
TO_UPLOAD_KEY); |
| 331 assertEquals("Minidump path should be for a fresh upload", | 389 assertEquals("Minidump path should be for a fresh upload", |
| 332 expectedRenamedMinidumpFile.getAbsolutePath(), filePath)
; | 390 expectedRenamedMinidumpFile.getAbsolutePath(), filePath)
; |
| 333 setFlag(startServiceFlag); | 391 setFlag(startServiceFlag); |
| 334 return new ComponentName(getPackageName(), MinidumpUploadService
.class.getName()); | 392 return new ComponentName(getPackageName(), MinidumpUploadService
.class.getName()); |
| 335 } | 393 } |
| 336 }; | 394 }; |
| 337 | 395 |
| 338 // Run test. | 396 // Run test. |
| 339 MinidumpUploadService.tryUploadCrashDumpWithLocalId(context, "f297dbcba7
a2d0bb"); | 397 MinidumpUploadService.tryUploadCrashDumpWithLocalId(context, "f297dbcba7
a2d0bb"); |
| 340 | 398 |
| 341 // Verify. | 399 // Verify. |
| 342 assertTrue("Should have called startService(...)", context.isFlagSet(sta
rtServiceFlag)); | 400 assertTrue("Should have called startService(...)", context.isFlagSet(sta
rtServiceFlag)); |
| 343 } | 401 } |
| 344 | 402 |
| 345 @SmallTest | 403 @SmallTest |
| 346 @Feature({"Android-AppBase"}) | 404 @Feature({"Android-AppBase"}) |
| 347 public void testHandleForceUploadCrash_FileDoesntExist() { | 405 public void testHandleForceUploadCrash_SkippedMinidumpFileExists_WithJobSche
duler() |
| 406 throws IOException { |
| 407 // The JobScheduler API is only available as of Android M. |
| 408 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return; |
| 409 setJobSchedulerEnabled(true); |
| 410 |
| 348 // Set up prerequisites. | 411 // Set up prerequisites. |
| 412 setUpMinidumpFile( |
| 413 new File(mCrashDir, "chromium-renderer-minidump-f297dbcba7a2d0bb
.skipped0.try3"), |
| 414 BOUNDARY); |
| 415 AdvancedMockContext context = |
| 416 new MinidumpPreparationContext(getInstrumentation().getTargetCon
text()); |
| 417 |
| 418 // Run test. |
| 419 MinidumpUploadService.tryUploadCrashDumpWithLocalId(context, "f297dbcba7
a2d0bb"); |
| 420 |
| 421 // Verify. |
| 422 final File expectedRenamedMinidumpFile = |
| 423 new File(mCrashDir, "chromium-renderer-minidump-f297dbcba7a2d0bb
.forced0.try0"); |
| 424 assertTrue("Should have renamed the minidump file for forced upload", |
| 425 expectedRenamedMinidumpFile.exists()); |
| 426 assertTrue("Should have tried to schedule an upload job", |
| 427 context.isFlagSet(TestJobScheduler.SCHEDULE_JOB_FLAG)); |
| 428 } |
| 429 |
| 430 @SmallTest |
| 431 @Feature({"Android-AppBase"}) |
| 432 public void testHandleForceUploadCrash_FileDoesntExist_SansJobScheduler() { |
| 433 // Set up prerequisites. |
| 434 setJobSchedulerEnabled(false); |
| 349 final String startServiceFlag = "startServiceFlag"; | 435 final String startServiceFlag = "startServiceFlag"; |
| 350 MinidumpPreparationContext context = new MinidumpPreparationContext( | 436 MinidumpPreparationContext context = new MinidumpPreparationContext( |
| 351 getInstrumentation().getTargetContext()) { | 437 getInstrumentation().getTargetContext()) { |
| 352 @Override | 438 @Override |
| 353 public ComponentName startService(Intent unused) { | 439 public ComponentName startService(Intent unused) { |
| 354 setFlag(startServiceFlag); | 440 setFlag(startServiceFlag); |
| 355 return new ComponentName(getPackageName(), MinidumpUploadService
.class.getName()); | 441 return new ComponentName(getPackageName(), MinidumpUploadService
.class.getName()); |
| 356 } | 442 } |
| 357 }; | 443 }; |
| 358 | 444 |
| 359 // Run test. | 445 // Run test. |
| 360 MinidumpUploadService.tryUploadCrashDumpWithLocalId(context, "f297dbcba7
a2d0bb"); | 446 MinidumpUploadService.tryUploadCrashDumpWithLocalId(context, "f297dbcba7
a2d0bb"); |
| 361 | 447 |
| 362 // Verify. | 448 // Verify. |
| 363 assertFalse( | 449 assertFalse( |
| 364 "Should not have called startService(...)", context.isFlagSet(st
artServiceFlag)); | 450 "Should not have called startService(...)", context.isFlagSet(st
artServiceFlag)); |
| 365 } | 451 } |
| 366 | 452 |
| 367 @SmallTest | 453 @SmallTest |
| 368 @Feature({"Android-AppBase"}) | 454 @Feature({"Android-AppBase"}) |
| 369 public void testHandleForceUploadCrash_FileAlreadyUploaded() throws IOExcept
ion { | 455 public void testHandleForceUploadCrash_FileDoesntExist_WithJobScheduler() th
rows IOException { |
| 456 // The JobScheduler API is only available as of Android M. |
| 457 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return; |
| 458 setJobSchedulerEnabled(true); |
| 459 |
| 370 // Set up prerequisites. | 460 // Set up prerequisites. |
| 371 File minidumpFile = | 461 AdvancedMockContext context = |
| 372 new File(mCrashDir, "chromium-renderer-minidump-f297dbcba7a2d0bb
.up0.try0"); | 462 new MinidumpPreparationContext(getInstrumentation().getTargetCon
text()); |
| 373 setUpMinidumpFile(minidumpFile, BOUNDARY); | 463 |
| 464 // Run test. |
| 465 MinidumpUploadService.tryUploadCrashDumpWithLocalId(context, "f297dbcba7
a2d0bb"); |
| 466 |
| 467 // Verify. |
| 468 assertFalse("Should not have tried to schedule an upload job", |
| 469 context.isFlagSet(TestJobScheduler.SCHEDULE_JOB_FLAG)); |
| 470 } |
| 471 |
| 472 @SmallTest |
| 473 @Feature({"Android-AppBase"}) |
| 474 public void testHandleForceUploadCrash_FileAlreadyUploaded_SansJobScheduler(
) |
| 475 throws IOException { |
| 476 // Set up prerequisites. |
| 477 setJobSchedulerEnabled(false); |
| 478 setUpMinidumpFile( |
| 479 new File(mCrashDir, "chromium-renderer-minidump-f297dbcba7a2d0bb
.up0.try0"), |
| 480 BOUNDARY); |
| 374 final String startServiceFlag = "startServiceFlag"; | 481 final String startServiceFlag = "startServiceFlag"; |
| 375 MinidumpPreparationContext context = new MinidumpPreparationContext( | 482 MinidumpPreparationContext context = new MinidumpPreparationContext( |
| 376 getInstrumentation().getTargetContext()) { | 483 getInstrumentation().getTargetContext()) { |
| 377 @Override | 484 @Override |
| 378 public ComponentName startService(Intent unused) { | 485 public ComponentName startService(Intent unused) { |
| 379 setFlag(startServiceFlag); | 486 setFlag(startServiceFlag); |
| 380 return new ComponentName(getPackageName(), MinidumpUploadService
.class.getName()); | 487 return new ComponentName(getPackageName(), MinidumpUploadService
.class.getName()); |
| 381 } | 488 } |
| 382 }; | 489 }; |
| 383 | 490 |
| 384 // Run test. | 491 // Run test. |
| 385 MinidumpUploadService.tryUploadCrashDumpWithLocalId(context, "f297dbcba7
a2d0bb"); | 492 MinidumpUploadService.tryUploadCrashDumpWithLocalId(context, "f297dbcba7
a2d0bb"); |
| 386 | 493 |
| 387 // Verify. | 494 // Verify. |
| 388 assertFalse( | 495 assertFalse( |
| 389 "Should not have called startService(...)", context.isFlagSet(st
artServiceFlag)); | 496 "Should not have called startService(...)", context.isFlagSet(st
artServiceFlag)); |
| 390 } | 497 } |
| 391 | 498 |
| 392 @SmallTest | 499 @SmallTest |
| 393 @Feature({"Android-AppBase"}) | 500 @Feature({"Android-AppBase"}) |
| 501 public void testHandleForceUploadCrash_FileAlreadyUploaded_WithJobScheduler(
) |
| 502 throws IOException { |
| 503 // The JobScheduler API is only available as of Android M. |
| 504 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return; |
| 505 setJobSchedulerEnabled(true); |
| 506 |
| 507 // Set up prerequisites. |
| 508 setUpMinidumpFile( |
| 509 new File(mCrashDir, "chromium-renderer-minidump-f297dbcba7a2d0bb
.up0.try0"), |
| 510 BOUNDARY); |
| 511 AdvancedMockContext context = |
| 512 new MinidumpPreparationContext(getInstrumentation().getTargetCon
text()); |
| 513 |
| 514 // Run test. |
| 515 MinidumpUploadService.tryUploadCrashDumpWithLocalId(context, "f297dbcba7
a2d0bb"); |
| 516 |
| 517 // Verify. |
| 518 assertFalse("Should not have tried to schedule an upload job", |
| 519 context.isFlagSet(TestJobScheduler.SCHEDULE_JOB_FLAG)); |
| 520 } |
| 521 |
| 522 @SmallTest |
| 523 @Feature({"Android-AppBase"}) |
| 394 public void testGetCrashType1() throws IOException { | 524 public void testGetCrashType1() throws IOException { |
| 395 final File minidumpFile = new File(mCrashDir, "chromium_renderer-123.dmp
"); | 525 final File minidumpFile = new File(mCrashDir, "chromium_renderer-123.dmp
"); |
| 396 setUpMinidumpFile(minidumpFile, BOUNDARY, "browser"); | 526 setUpMinidumpFile(minidumpFile, BOUNDARY, "browser"); |
| 397 assertEquals(BROWSER, MinidumpUploadService.getCrashType(minidumpFile.ge
tAbsolutePath())); | 527 assertEquals(BROWSER, MinidumpUploadService.getCrashType(minidumpFile.ge
tAbsolutePath())); |
| 398 } | 528 } |
| 399 | 529 |
| 400 @SmallTest | 530 @SmallTest |
| 401 @Feature({"Android-AppBase"}) | 531 @Feature({"Android-AppBase"}) |
| 402 public void testGetCrashType2() throws IOException { | 532 public void testGetCrashType2() throws IOException { |
| 403 final File minidumpFile = new File(mCrashDir, "chromium_renderer-123.dmp
"); | 533 final File minidumpFile = new File(mCrashDir, "chromium_renderer-123.dmp
"); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 433 | 563 |
| 434 public MinidumpPreparationContext(Context targetContext, MinidumpUploadS
ervice service) { | 564 public MinidumpPreparationContext(Context targetContext, MinidumpUploadS
ervice service) { |
| 435 super(targetContext); | 565 super(targetContext); |
| 436 mService = service; | 566 mService = service; |
| 437 } | 567 } |
| 438 | 568 |
| 439 @Override | 569 @Override |
| 440 public File getCacheDir() { | 570 public File getCacheDir() { |
| 441 return mCacheDir; | 571 return mCacheDir; |
| 442 } | 572 } |
| 573 |
| 574 @Override |
| 575 public Object getSystemService(String name) { |
| 576 if (Context.JOB_SCHEDULER_SERVICE.equals(name)) { |
| 577 assertTrue("Should only access the JobScheduler when it is enabl
ed.", |
| 578 ChromeFeatureList.isEnabled( |
| 579 ChromeFeatureList.UPLOAD_CRASH_REPORTS_USING_JOB
_SCHEDULER)); |
| 580 return new TestJobScheduler(this); |
| 581 } |
| 582 |
| 583 return super.getSystemService(name); |
| 584 } |
| 443 } | 585 } |
| 444 | 586 |
| 445 /** | 587 /** |
| 588 * A JobScheduler wrapper that verifies that the expected properties are set
correctly. |
| 589 */ |
| 590 @TargetApi(Build.VERSION_CODES.M) |
| 591 private static class TestJobScheduler extends JobScheduler { |
| 592 static final String SCHEDULE_JOB_FLAG = "scheduleJobFlag"; |
| 593 |
| 594 private final AdvancedMockContext mContext; |
| 595 |
| 596 TestJobScheduler(AdvancedMockContext context) { |
| 597 mContext = context; |
| 598 } |
| 599 |
| 600 @Override |
| 601 public void cancel(int jobId) {} |
| 602 |
| 603 @Override |
| 604 public void cancelAll() {} |
| 605 |
| 606 @Override |
| 607 public List<JobInfo> getAllPendingJobs() { |
| 608 return null; |
| 609 } |
| 610 |
| 611 @Override |
| 612 public JobInfo getPendingJob(int jobId) { |
| 613 return null; |
| 614 } |
| 615 |
| 616 @Override |
| 617 public int schedule(JobInfo job) { |
| 618 mContext.setFlag(SCHEDULE_JOB_FLAG); |
| 619 assertEquals(TaskIds.CHROME_MINIDUMP_UPLOADING_JOB_ID, job.getId()); |
| 620 assertEquals(ChromeMinidumpUploadJobService.class.getName(), |
| 621 job.getService().getClassName()); |
| 622 return 0; |
| 623 } |
| 624 }; |
| 625 |
| 626 /** |
| 446 * A fake callable, that just counts the number of times it is called. | 627 * A fake callable, that just counts the number of times it is called. |
| 447 * | 628 * |
| 448 * It can be constructed with the wanted return-value of the call()-method. | 629 * It can be constructed with the wanted return-value of the call()-method. |
| 449 */ | 630 */ |
| 450 private static class CountedMinidumpUploadCallable extends MinidumpUploadCal
lable { | 631 private static class CountedMinidumpUploadCallable extends MinidumpUploadCal
lable { |
| 451 private int mCalledCount; | 632 private int mCalledCount; |
| 452 @MinidumpUploadCallable.MinidumpUploadStatus private final int mResult; | 633 @MinidumpUploadCallable.MinidumpUploadStatus private final int mResult; |
| 453 private final boolean mTriggerNetworkChange; | 634 private final boolean mTriggerNetworkChange; |
| 454 | 635 |
| 455 /** | 636 /** |
| 456 * Creates a fake callable, that just counts the number of times it is c
alled. | 637 * Creates a fake callable, that just counts the number of times it is c
alled. |
| 457 * | 638 * |
| 458 * @param result the value to return from the call()-method. | 639 * @param result the value to return from the call()-method. |
| 459 * @param networkChange Should trigger a network change after this calla
ble is finished. | 640 * @param networkChange Should trigger a network change after this calla
ble is finished. |
| 460 * This essentially triggers a retry if result is set to fail. | 641 * This essentially triggers a retry if result is set to fail. |
| 461 */ | 642 */ |
| 462 private CountedMinidumpUploadCallable(String fileName, int result, boole
an networkChange) { | 643 private CountedMinidumpUploadCallable(String fileName, int result, boole
an networkChange) { |
| 463 super(new File(fileName), null, null, null); | 644 super(new File(fileName), null, null, null); |
| 464 this.mResult = result; | 645 this.mResult = result; |
| 465 this.mTriggerNetworkChange = networkChange; | 646 this.mTriggerNetworkChange = networkChange; |
| 466 } | 647 } |
| 467 | 648 |
| 468 @Override | 649 @Override |
| 469 public Integer call() { | 650 public Integer call() { |
| 470 ++mCalledCount; | 651 ++mCalledCount; |
| 471 return mResult; | 652 return mResult; |
| 472 } | 653 } |
| 473 } | 654 } |
| 474 } | 655 } |
| OLD | NEW |