@SmallTest
 @Feature({"Cronet"})
 // Tests that creating a ByteBufferUploadProvider using a byte array with an
 // offset gives a ByteBuffer with position 0. crbug.com/603124.
 public void testCreateByteBufferUploadWithArrayOffset() throws Exception {
   TestUrlRequestCallback callback = new TestUrlRequestCallback();
   // This URL will trigger a rewind().
   UrlRequest.Builder builder =
       new UrlRequest.Builder(
           NativeTestServer.getRedirectToEchoBody(),
           callback,
           callback.getExecutor(),
           mTestFramework.mCronetEngine);
   builder.addHeader("Content-Type", "useless/string");
   byte[] uploadData = LOREM.getBytes("UTF-8");
   int offset = 5;
   byte[] uploadDataWithPadding = new byte[uploadData.length + offset];
   System.arraycopy(uploadData, 0, uploadDataWithPadding, offset, uploadData.length);
   UploadDataProvider dataProvider =
       UploadDataProviders.create(uploadDataWithPadding, offset, uploadData.length);
   assertEquals(uploadData.length, dataProvider.getLength());
   builder.setUploadDataProvider(dataProvider, callback.getExecutor());
   UrlRequest urlRequest = builder.build();
   urlRequest.start();
   callback.blockForDone();
   assertEquals(200, callback.mResponseInfo.getHttpStatusCode());
   assertEquals(LOREM, callback.mResponseAsString);
 }
 @SmallTest
 @Feature({"Cronet"})
 public void testFileProvider() throws Exception {
   TestUrlRequestCallback callback = new TestUrlRequestCallback();
   UrlRequest.Builder builder =
       new UrlRequest.Builder(
           NativeTestServer.getRedirectToEchoBody(),
           callback,
           callback.getExecutor(),
           mTestFramework.mCronetEngine);
   UploadDataProvider dataProvider = UploadDataProviders.create(mFile);
   builder.setUploadDataProvider(dataProvider, callback.getExecutor());
   builder.addHeader("Content-Type", "useless/string");
   builder.build().start();
   callback.blockForDone();
   assertEquals(200, callback.mResponseInfo.getHttpStatusCode());
   assertEquals(LOREM, callback.mResponseAsString);
 }
  @SmallTest
  @Feature({"Cronet"})
  public void testNoErrorWhenCanceledDuringStart() throws Exception {
    TestUrlRequestCallback callback = new TestUrlRequestCallback();
    UrlRequest.Builder builder =
        new UrlRequest.Builder(
            NativeTestServer.getEchoBodyURL(),
            callback,
            callback.getExecutor(),
            mTestFramework.mCronetEngine);
    final ConditionVariable first = new ConditionVariable();
    final ConditionVariable second = new ConditionVariable();
    builder.addHeader("Content-Type", "useless/string");
    builder.setUploadDataProvider(
        new UploadDataProvider() {
          @Override
          public long getLength() throws IOException {
            first.open();
            second.block();
            return 0;
          }

          @Override
          public void read(UploadDataSink uploadDataSink, ByteBuffer byteBuffer)
              throws IOException {}

          @Override
          public void rewind(UploadDataSink uploadDataSink) throws IOException {}
        },
        callback.getExecutor());
    UrlRequest urlRequest = builder.build();
    urlRequest.start();
    first.block();
    urlRequest.cancel();
    second.open();
    callback.blockForDone();
    assertTrue(callback.mOnCanceledCalled);
  }
  @SmallTest
  @Feature({"Cronet"})
  public void testNoErrorWhenExceptionDuringStart() throws Exception {
    TestUrlRequestCallback callback = new TestUrlRequestCallback();
    UrlRequest.Builder builder =
        new UrlRequest.Builder(
            NativeTestServer.getEchoBodyURL(),
            callback,
            callback.getExecutor(),
            mTestFramework.mCronetEngine);
    final ConditionVariable first = new ConditionVariable();
    final String exceptionMessage = "Bad Length";
    builder.addHeader("Content-Type", "useless/string");
    builder.setUploadDataProvider(
        new UploadDataProvider() {
          @Override
          public long getLength() throws IOException {
            first.open();
            throw new IOException(exceptionMessage);
          }

          @Override
          public void read(UploadDataSink uploadDataSink, ByteBuffer byteBuffer)
              throws IOException {}

          @Override
          public void rewind(UploadDataSink uploadDataSink) throws IOException {}
        },
        callback.getExecutor());
    UrlRequest urlRequest = builder.build();
    urlRequest.start();
    first.block();
    callback.blockForDone();
    assertFalse(callback.mOnCanceledCalled);
    assertEquals(UrlRequestError.LISTENER_EXCEPTION_THROWN, callback.mError.getErrorCode());
    assertEquals("Exception received from UploadDataProvider", callback.mError.getMessage());
    assertEquals(exceptionMessage, callback.mError.getCause().getMessage());
  }
  @SmallTest
  @Feature({"Cronet"})
  public void testBadFileDescriptorProvider() throws Exception {
    TestUrlRequestCallback callback = new TestUrlRequestCallback();
    UrlRequest.Builder builder =
        new UrlRequest.Builder(
            NativeTestServer.getRedirectToEchoBody(),
            callback,
            callback.getExecutor(),
            mTestFramework.mCronetEngine);
    ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe();
    try {
      UploadDataProvider dataProvider = UploadDataProviders.create(pipe[0]);
      builder.setUploadDataProvider(dataProvider, callback.getExecutor());
      builder.addHeader("Content-Type", "useless/string");
      builder.build().start();
      callback.blockForDone();

      assertTrue(callback.mError.getCause() instanceof IllegalArgumentException);
    } finally {
      pipe[1].close();
    }
  }