1 // Copyright 2021 The Android Open Source Project 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package com.google.android.downloader; 16 17 import static com.google.common.truth.Truth.assertThat; 18 import static com.google.common.util.concurrent.MoreExecutors.listeningDecorator; 19 import static java.nio.charset.StandardCharsets.UTF_8; 20 import static java.util.concurrent.Executors.newSingleThreadExecutor; 21 22 import com.google.common.io.Files; 23 import com.google.common.util.concurrent.ListenableFuture; 24 import com.google.common.util.concurrent.ListeningExecutorService; 25 import java.io.File; 26 import java.net.HttpURLConnection; 27 import java.nio.channels.FileChannel; 28 import java.nio.file.StandardOpenOption; 29 import org.junit.After; 30 import org.junit.Before; 31 import org.junit.Rule; 32 import org.junit.Test; 33 import org.junit.rules.TemporaryFolder; 34 import org.junit.runner.RunWith; 35 import org.junit.runners.JUnit4; 36 37 /** Unit tests for PlatformUrlEngine. */ 38 @RunWith(JUnit4.class) 39 public class PlatformUrlEngineTest { 40 @Rule public TemporaryFolder temporaryFolder = new TemporaryFolder(); 41 42 private MockWebServerUrlEngineTestHelper testHelper; 43 private PlatformUrlEngine engine; 44 private ListeningExecutorService executorService; 45 46 @Before setUp()47 public void setUp() { 48 executorService = listeningDecorator(newSingleThreadExecutor()); 49 testHelper = 50 new MockWebServerUrlEngineTestHelper( 51 temporaryFolder, new TestingExecutorService(executorService)); 52 engine = 53 new PlatformUrlEngine( 54 executorService, /* connectTimeoutMs= */ 1000, /* readTimeoutMs= */ 1000); 55 } 56 57 @After tearDown()58 public void tearDown() throws Exception { 59 testHelper.tearDown(); 60 executorService.shutdown(); 61 } 62 63 @Test executeRequest_normalResponse_succeeds()64 public void executeRequest_normalResponse_succeeds() throws Exception { 65 testHelper.executeRequest_normalResponse_succeeds(engine); 66 } 67 68 @Test executeRequest_responseThrottled_succeeds()69 public void executeRequest_responseThrottled_succeeds() throws Exception { 70 testHelper.executeRequest_responseThrottled_succeeds(engine); 71 } 72 73 @Test executeRequest_largeResponse_succeeds()74 public void executeRequest_largeResponse_succeeds() throws Exception { 75 testHelper.executeRequest_largeResponse_succeeds( 76 engine, PlatformUrlEngine.BUFFER_SIZE_BYTES * 3); 77 } 78 79 @Test executeRequest_closeBeforeWrite_failsAborted()80 public void executeRequest_closeBeforeWrite_failsAborted() throws Exception { 81 testHelper.executeRequest_closeBeforeWrite_failsAborted(engine); 82 } 83 84 @Test executeRequest_serverError_failsInternalError()85 public void executeRequest_serverError_failsInternalError() throws Exception { 86 testHelper.executeRequest_serverError_failsInternalError(engine); 87 } 88 89 @Test executeRequest_networkError_failsInternalError()90 public void executeRequest_networkError_failsInternalError() throws Exception { 91 testHelper.executeRequest_networkError_failsInternalError(engine); 92 } 93 94 @Test executeRequest_writeError_failsInternalError()95 public void executeRequest_writeError_failsInternalError() throws Exception { 96 testHelper.executeRequest_writeError_failsInternalError(engine); 97 } 98 99 @Test executeRequest_requestCanceled_requestNeverSent()100 public void executeRequest_requestCanceled_requestNeverSent() throws Exception { 101 testHelper.executeRequest_requestCanceled_requestNeverSent(engine); 102 } 103 104 @Test executeRequest_invalidUrl_failsInvalidArgument()105 public void executeRequest_invalidUrl_failsInvalidArgument() { 106 testHelper.executeRequest_invalidUrl_failsInvalidArgument(engine); 107 } 108 109 @Test executeRequest_fileUrl()110 public void executeRequest_fileUrl() throws Exception { 111 // Note: File url testing doesn't exist in MockWebServerUrlEngineTestHelper because 112 // it doesn't involve the MockWebServer and doesn't apply to all UrlEngine implementations. 113 String message = "foobar"; 114 File sourceFile = temporaryFolder.newFile(); 115 Files.asCharSink(sourceFile, UTF_8).write(message); 116 117 String url = sourceFile.toURI().toURL().toString(); 118 UrlRequest request = engine.createRequest(url).build(); 119 ListenableFuture<? extends UrlResponse> responseFuture = request.send(); 120 UrlResponse response = responseFuture.get(); 121 122 File targetFile = temporaryFolder.newFile(); 123 FileChannel channel = FileChannel.open(targetFile.toPath(), StandardOpenOption.WRITE); 124 ListenableFuture<Long> writeFuture = response.readResponseBody(channel); 125 long bytesWritten = writeFuture.get(); 126 response.close(); 127 channel.close(); 128 129 assertThat(bytesWritten).isGreaterThan(0L); 130 assertThat(Files.asCharSource(targetFile, UTF_8).read()).isEqualTo(message); 131 assertThat(response.getResponseCode()).isEqualTo(HttpURLConnection.HTTP_OK); 132 } 133 } 134