Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(120)

Side by Side Diff: android_webview/javatests/src/org/chromium/android_webview/test/crash/MinidumpUploaderTest.java

Issue 2682913006: [Android WebView] Always schedule new upload job after copying minidump. (Closed)
Patch Set: Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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.android_webview.test.crash; 5 package org.chromium.android_webview.test.crash;
6 6
7 import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout; 7 import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout;
8 8
9 import android.content.Context; 9 import android.content.Context;
10 import android.os.ParcelFileDescriptor; 10 import android.os.ParcelFileDescriptor;
(...skipping 13 matching lines...) Expand all
24 import org.chromium.components.minidump_uploader.util.CrashReportingPermissionMa nager; 24 import org.chromium.components.minidump_uploader.util.CrashReportingPermissionMa nager;
25 import org.chromium.components.minidump_uploader.util.HttpURLConnectionFactory; 25 import org.chromium.components.minidump_uploader.util.HttpURLConnectionFactory;
26 26
27 import java.io.File; 27 import java.io.File;
28 import java.io.FileInputStream; 28 import java.io.FileInputStream;
29 import java.io.FileNotFoundException; 29 import java.io.FileNotFoundException;
30 import java.io.IOException; 30 import java.io.IOException;
31 import java.io.InterruptedIOException; 31 import java.io.InterruptedIOException;
32 import java.io.OutputStream; 32 import java.io.OutputStream;
33 import java.net.HttpURLConnection; 33 import java.net.HttpURLConnection;
34 import java.net.MalformedURLException;
35 import java.net.URL;
34 import java.util.ArrayList; 36 import java.util.ArrayList;
35 import java.util.List; 37 import java.util.List;
36 import java.util.concurrent.CountDownLatch; 38 import java.util.concurrent.CountDownLatch;
37 import java.util.concurrent.TimeUnit; 39 import java.util.concurrent.TimeUnit;
38 40
39 /** 41 /**
40 * Instrumentation tests for MinidumpUploader. 42 * Instrumentation tests for MinidumpUploader.
41 */ 43 */
42 public class MinidumpUploaderTest extends CrashTestCase { 44 public class MinidumpUploaderTest extends CrashTestCase {
43 private static final String TAG = "MinidumpUploaderTest"; 45 private static final String TAG = "MinidumpUploaderTest";
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 // This file should have been left untouched. 141 // This file should have been left untouched.
140 assertTrue(maxTriesFile.exists()); 142 assertTrue(maxTriesFile.exists());
141 } 143 }
142 144
143 /** 145 /**
144 * Utility method for running {@param minidumpUploader}.uploadAllMinidumps o n the UI thread to 146 * Utility method for running {@param minidumpUploader}.uploadAllMinidumps o n the UI thread to
145 * avoid breaking any assertions about running on the UI thread. 147 * avoid breaking any assertions about running on the UI thread.
146 */ 148 */
147 private static void uploadAllMinidumpsOnUiThread(final MinidumpUploader mini dumpUploader, 149 private static void uploadAllMinidumpsOnUiThread(final MinidumpUploader mini dumpUploader,
148 final MinidumpUploader.UploadsFinishedCallback uploadsFinishedCallba ck) { 150 final MinidumpUploader.UploadsFinishedCallback uploadsFinishedCallba ck) {
151 uploadAllMinidumpsOnUiThread(
152 minidumpUploader, uploadsFinishedCallback, false /* blockUntilJo bPosted */);
153 }
154
155 private static void uploadAllMinidumpsOnUiThread(final MinidumpUploader mini dumpUploader,
156 final MinidumpUploader.UploadsFinishedCallback uploadsFinishedCallba ck,
157 boolean blockUntilJobPosted) {
158 final CountDownLatch jobPostedLatch = new CountDownLatch(1);
149 ThreadUtils.runOnUiThread(new Runnable() { 159 ThreadUtils.runOnUiThread(new Runnable() {
150 @Override 160 @Override
151 public void run() { 161 public void run() {
152 minidumpUploader.uploadAllMinidumps(uploadsFinishedCallback); 162 minidumpUploader.uploadAllMinidumps(uploadsFinishedCallback);
163 jobPostedLatch.countDown();
153 } 164 }
154 }); 165 });
166 if (blockUntilJobPosted) {
167 try {
168 jobPostedLatch.await();
169 } catch (InterruptedException e) {
170 throw new RuntimeException(e);
Ilya Sherman 2017/02/11 01:00:47 What's the reason to catch the exception just to r
gsennton 2017/02/13 10:46:55 Just to avoid having to declare the Exception type
171 }
172 }
155 } 173 }
156 174
157 private static void uploadMinidumpsSync( 175 private static void uploadMinidumpsSync(
158 MinidumpUploader minidumpUploader, final boolean expectReschedule) { 176 MinidumpUploader minidumpUploader, final boolean expectReschedule) {
159 final CountDownLatch uploadsFinishedLatch = new CountDownLatch(1); 177 final CountDownLatch uploadsFinishedLatch = new CountDownLatch(1);
160 uploadAllMinidumpsOnUiThread( 178 uploadAllMinidumpsOnUiThread(
161 minidumpUploader, new MinidumpUploader.UploadsFinishedCallback() { 179 minidumpUploader, new MinidumpUploader.UploadsFinishedCallback() {
162 @Override 180 @Override
163 public void uploadsFinished(boolean reschedule) { 181 public void uploadsFinished(boolean reschedule) {
164 assertEquals(expectReschedule, reschedule); 182 assertEquals(expectReschedule, reschedule);
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
269 expectedSecondFile = new File(mCrashDir, secondFile.getName().replac e(".dmp", ".up")); 287 expectedSecondFile = new File(mCrashDir, secondFile.getName().replac e(".dmp", ".up"));
270 } else { 288 } else {
271 File uploadedFirstFile = 289 File uploadedFirstFile =
272 new File(mCrashDir, firstFile.getName().replace(".dmp", ".up ")); 290 new File(mCrashDir, firstFile.getName().replace(".dmp", ".up "));
273 assertTrue(uploadedFirstFile.exists()); 291 assertTrue(uploadedFirstFile.exists());
274 expectedSecondFile = new File(mCrashDir, secondFile.getName() + ".tr y1"); 292 expectedSecondFile = new File(mCrashDir, secondFile.getName() + ".tr y1");
275 } 293 }
276 assertTrue(expectedSecondFile.exists()); 294 assertTrue(expectedSecondFile.exists());
277 } 295 }
278 296
279 private static class StallingOutputStream extends OutputStream { 297 private static class StallingHttpUrlConnectionFactory implements HttpURLConn ectionFactory {
280 @Override 298 private final CountDownLatch mStopStallingLatch;
281 public void write(int b) throws IOException { 299 private final boolean mSucceed;
300
301 private class StallingOutputStream extends OutputStream {
302 @Override
303 public void write(int b) throws IOException {
304 try {
305 mStopStallingLatch.await();
306 } catch (InterruptedException e) {
307 throw new InterruptedIOException(e.toString());
308 }
309 if (!mSucceed) {
310 throw new IOException();
311 }
312 }
313 }
314
315 public StallingHttpUrlConnectionFactory(CountDownLatch stopStallingLatch , boolean succeed) {
316 mStopStallingLatch = stopStallingLatch;
317 mSucceed = succeed;
318 }
319
320 public HttpURLConnection createHttpURLConnection(String url) {
282 try { 321 try {
283 TimeUnit.MINUTES.sleep(100); 322 return new MinidumpUploadCallableTest.TestHttpURLConnection(new URL(url)) {
284 } catch (InterruptedException e) { 323 @Override
285 throw new InterruptedIOException(e.toString()); 324 public OutputStream getOutputStream() {
325 return new StallingOutputStream();
326 }
327 };
328 } catch (MalformedURLException e) {
329 return null;
286 } 330 }
287 } 331 }
288 } 332 }
289 333
290 private static class StallingHttpUrlConnectionFactory implements HttpURLConn ectionFactory {
291 public HttpURLConnection createHttpURLConnection(String url) {
292 return new HttpURLConnection(null) {
293 @Override
294 public OutputStream getOutputStream() throws IOException {
295 return new StallingOutputStream();
296 }
297
298 @Override
299 public void connect() {}
300
301 @Override
302 public void disconnect() {}
303
304 @Override
305 public boolean usingProxy() {
306 return false;
307 }
308 };
309 }
310 }
311
312 private static class FailingHttpUrlConnectionFactory implements HttpURLConne ctionFactory { 334 private static class FailingHttpUrlConnectionFactory implements HttpURLConne ctionFactory {
313 public HttpURLConnection createHttpURLConnection(String url) { 335 public HttpURLConnection createHttpURLConnection(String url) {
314 return null; 336 return null;
315 } 337 }
316 } 338 }
317 339
318 /** 340 /**
319 * Test that ensure we can interrupt the MinidumpUploader when uploading min idumps. 341 * Test that ensures we can interrupt the MinidumpUploader when uploading mi nidumps.
320 */ 342 */
321 @MediumTest 343 @MediumTest
322 public void testCancelMinidumpUploads() throws IOException { 344 public void testCancelMinidumpUploadsFailedUpload() throws IOException {
345 testCancellation(false /* successfulUpload */);
346 }
347
348 /**
349 * Test that ensures interrupting our upload-job will not interrupt the firs t upload.
350 */
351 @MediumTest
352 public void testCancelingWontCancelFirstUpload() throws IOException {
353 testCancellation(true /* successfulUpload */);
354 }
355
356 private void testCancellation(final boolean successfulUpload) throws IOExcep tion {
323 final CrashReportingPermissionManager permManager = 357 final CrashReportingPermissionManager permManager =
324 new MockCrashReportingPermissionManager() { 358 new MockCrashReportingPermissionManager() {
325 { mIsEnabledForTests = true; } 359 { mIsEnabledForTests = true; }
326 }; 360 };
327 MinidumpUploader minidumpUploader = new MinidumpUploaderImpl( 361 final CountDownLatch stopStallingLatch = new CountDownLatch(1);
362 MinidumpUploaderImpl minidumpUploader = new MinidumpUploaderImpl(
328 getInstrumentation().getTargetContext(), false /* cleanOutMinidu mps */) { 363 getInstrumentation().getTargetContext(), false /* cleanOutMinidu mps */) {
329 @Override 364 @Override
330 public MinidumpUploadCallable createMinidumpUploadCallable( 365 public MinidumpUploadCallable createMinidumpUploadCallable(
331 File minidumpFile, File logfile) { 366 File minidumpFile, File logfile) {
332 return new MinidumpUploadCallable( 367 return new MinidumpUploadCallable(minidumpFile, logfile,
333 minidumpFile, logfile, new StallingHttpUrlConnectionFact ory(), permManager); 368 new StallingHttpUrlConnectionFactory(stopStallingLatch, successfulUpload),
369 permManager);
334 } 370 }
335 @Override 371 @Override
336 public PlatformServiceBridge createPlatformServiceBridge() { 372 public PlatformServiceBridge createPlatformServiceBridge() {
337 return new TestPlatformServiceBridge( 373 return new TestPlatformServiceBridge(
338 true /* canUseGms*/, permManager.isUsageAndCrashReportin gPermittedByUser()); 374 true /* canUseGms*/, permManager.isUsageAndCrashReportin gPermittedByUser());
339 } 375 }
340 }; 376 };
341 377
342 File firstFile = createMinidumpFileInCrashDir("123_abc.dmp0"); 378 File firstFile = createMinidumpFileInCrashDir("123_abc.dmp0");
343 File nonExpectedFirstUploadFile = new File(mCrashDir, firstFile.getName( ) + ".up"); 379 File expectedFirstUploadFile =
344 File nonExpectedFirstRetryFile = new File(mCrashDir, firstFile.getName() + ".try1"); 380 new File(mCrashDir, firstFile.getName().replace(".dmp", ".up"));
381 File expectedFirstRetryFile = new File(mCrashDir, firstFile.getName() + ".try1");
345 382
346 // This is run on the UI thread to avoid failing any assertOnUiThread as sertions. 383 // This is run on the UI thread to avoid failing any assertOnUiThread as sertions.
347 uploadAllMinidumpsOnUiThread( 384 uploadAllMinidumpsOnUiThread(minidumpUploader,
348 minidumpUploader, new MinidumpUploader.UploadsFinishedCallback() { 385 new MinidumpUploader.UploadsFinishedCallback() {
349 @Override 386 @Override
350 public void uploadsFinished(boolean reschedule) { 387 public void uploadsFinished(boolean reschedule) {
351 fail("This method shouldn't be called when we interrupt uploads."); 388 if (successfulUpload) {
389 assertFalse(reschedule);
390 } else {
391 fail("This method shouldn't be called when a cancele d upload fails.");
392 }
352 } 393 }
353 }); 394 },
395 // Block until job posted - otherwise the worker thread might no t have been created
396 // before we try to join it.
397 true /* blockUntilJobPosted */);
354 minidumpUploader.cancelUploads(); 398 minidumpUploader.cancelUploads();
399 stopStallingLatch.countDown();
400 // Wait until our job finished.
401 try {
402 minidumpUploader.joinWorkerThreadForTesting();
403 } catch (InterruptedException e) {
404 throw new RuntimeException(e);
405 }
355 406
356 assertTrue(firstFile.exists()); 407 if (successfulUpload) {
357 assertFalse(nonExpectedFirstUploadFile.exists()); 408 // When the upload succeeds we expect the file to be renamed.
358 assertFalse(nonExpectedFirstRetryFile.exists()); 409 assertFalse(firstFile.exists());
410 assertTrue(expectedFirstUploadFile.exists());
411 assertFalse(expectedFirstRetryFile.exists());
412 } else {
413 // When the upload fails we won't change the minidump at all.
414 assertTrue(firstFile.exists());
415 assertFalse(expectedFirstUploadFile.exists());
416 assertFalse(expectedFirstRetryFile.exists());
417 }
359 } 418 }
360 419
361 /** 420 /**
362 * Ensures that the minidump copying works together with the minidump upload ing. 421 * Ensures that the minidump copying works together with the minidump upload ing.
363 */ 422 */
364 @MediumTest 423 @MediumTest
365 public void testCopyAndUploadWebViewMinidump() throws FileNotFoundException, IOException { 424 public void testCopyAndUploadWebViewMinidump() throws FileNotFoundException, IOException {
366 final CrashFileManager fileManager = new CrashFileManager( 425 final CrashFileManager fileManager = new CrashFileManager(
367 CrashReceiverService.getWebViewCrashDir(getInstrumentation().get TargetContext())); 426 CrashReceiverService.getWebViewCrashDir(getInstrumentation().get TargetContext()));
368 // Note that these minidump files are set up directly in the cache dir - not in the WebView 427 // Note that these minidump files are set up directly in the cache dir - not in the WebView
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
612 assertEquals(numMinidumps, uploadedFiles.length); 671 assertEquals(numMinidumps, uploadedFiles.length);
613 return uploadedFiles; 672 return uploadedFiles;
614 } 673 }
615 674
616 private File createMinidumpFileInCrashDir(String name) throws IOException { 675 private File createMinidumpFileInCrashDir(String name) throws IOException {
617 File minidumpFile = new File(mCrashDir, name); 676 File minidumpFile = new File(mCrashDir, name);
618 setUpMinidumpFile(minidumpFile, BOUNDARY); 677 setUpMinidumpFile(minidumpFile, BOUNDARY);
619 return minidumpFile; 678 return minidumpFile;
620 } 679 }
621 } 680 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698