@SuppressFBWarnings("RV_RETURN_VALUE_IGNORED_BAD_PRACTICE")
  private void runUploadCrashTest(final List<CountedMinidumpUploadCallable> callables)
      throws IOException, InterruptedException {
    // Setup prerequisites.
    // This version of the service overrides the createMinidumpUploadCallable(...) to be able
    // to return fake ones. It also ensures that the service never tries to create a callable
    // too many times.
    TestMinidumpUploadService service =
        new TestMinidumpUploadService() {
          int mIndex = 0;
          boolean mTriggerNetworkChange = false;

          @Override
          MinidumpUploadCallable createMinidumpUploadCallable(File minidumpFile, File logfile) {
            if (mIndex >= callables.size()) {
              fail("Should not create callable number " + mIndex);
            }
            CountedMinidumpUploadCallable callable = callables.get(mIndex++);
            if (callable.mTriggerNetworkChange) {
              mTriggerNetworkChange = true;
            }
            return callable;
          }

          @Override
          protected void onHandleIntent(Intent intent) {
            try {
              runTestOnUiThread(
                  new Runnable() {
                    @Override
                    public void run() {
                      // Set up basically a fake.
                      if (!NetworkChangeNotifier.isInitialized()) {
                        NetworkChangeNotifier.init(getApplicationContext());
                      }
                    }
                  });
            } catch (Throwable t) {
              t.printStackTrace();
              fail("Failed to set up NetworkChangeNotifier");
            }

            super.onHandleIntent(intent);

            if (mTriggerNetworkChange) {
              mTriggerNetworkChange = false;
              try {
                runTestOnUiThread(
                    new Runnable() {
                      @Override
                      public void run() {
                        NetworkChangeNotifier.setAutoDetectConnectivityState(false);
                        // Quickly force the state to be connected and back to disconnected.
                        // An event should be triggered for retry logics.
                        NetworkChangeNotifier.forceConnectivityState(false);
                        NetworkChangeNotifier.forceConnectivityState(true);
                      }
                    });
              } catch (Throwable t) {
                t.printStackTrace();
                fail("Failed to trigger NetworkChangeNotifier");
              }
            }
          }
        };
    // Create a context that supports call to startService(...), where it runs the new service
    // calls on a handler thread. We pass in the MinidumpUploadService as an argument so we
    // can call it directly without going through the Android framework.
    final MinidumpPreparationContext context =
        new MinidumpPreparationContext(getInstrumentation().getTargetContext(), service) {
          Handler mHandler;

          {
            HandlerThread handlerThread =
                new HandlerThread("MinidumpUploadServiceTest Handler Thread");
            handlerThread.start();
            mHandler = new Handler(handlerThread.getLooper());
          }

          @Override
          public ComponentName startService(final Intent intentToCheck) {
            assertTrue(
                MinidumpUploadService.ACTION_UPLOAD.equals(intentToCheck.getAction())
                    || MinidumpUploadService.ACTION_FIND_ALL.equals(intentToCheck.getAction()));
            // Post to the handler thread to run the retry intent.
            mHandler.post(
                new Runnable() {
                  @Override
                  public void run() {
                    mService.onHandleIntent(intentToCheck);
                  }
                });
            return new ComponentName(getPackageName(), MinidumpUploadService.class.getName());
          }
        };
    // We need the context before we can attach it to the service, so since Context is
    // dependent on the service, we do this after context creation.
    service.attachBaseContextLate(context);
    // Create the file used for uploading.
    File minidumpFile = new File(mCrashDir, "chromium_renderer-111.dmp1");
    minidumpFile.createNewFile();
    File logfile = new File(mCacheDir, CrashFileManager.CRASH_DUMP_LOGFILE);
    setUpMinidumpFile(minidumpFile, BOUNDARY);

    // Run test.
    Intent uploadIntent = MinidumpUploadService.createUploadIntent(context, minidumpFile, logfile);
    uploadIntent.putExtra(MinidumpUploadService.FINISHED_LOGCAT_EXTRACTION_KEY, true);
    service.onCreate();
    service.onHandleIntent(uploadIntent);

    // Verify asynchronously.
    assertTrue(
        "All callables should have a call-count of 1",
        CriteriaHelper.pollForCriteria(
            new Criteria() {
              @Override
              public boolean isSatisfied() {
                for (CountedMinidumpUploadCallable callable : callables) {
                  if (callable.mCalledCount != 1) {
                    return false;
                  }
                }
                return true;
              }
            },
            MAX_TIMEOUT_MS,
            CHECK_INTERVAL_MS));
  }