From 8722531c081da8c11e56ceaaf8ea4e06c0406bb2 Mon Sep 17 00:00:00 2001 From: Chidera Olibie Date: Tue, 28 Feb 2023 14:36:43 +0000 Subject: [PATCH] Cronet: Add bidirectionalStream GET request test Bug: 251012627 Test: atest CtsNetHttpTestCases Change-Id: Ie55ea28a82c5929f0c61ba2b1e7acdf990eba68b --- .../net/http/cts/BidirectionalStreamTest.kt | 81 +++++++++++++++++++ .../util/TestBidirectionalStreamCallback.java | 53 +++++++++++- 2 files changed, 132 insertions(+), 2 deletions(-) create mode 100644 Cronet/tests/cts/src/android/net/http/cts/BidirectionalStreamTest.kt diff --git a/Cronet/tests/cts/src/android/net/http/cts/BidirectionalStreamTest.kt b/Cronet/tests/cts/src/android/net/http/cts/BidirectionalStreamTest.kt new file mode 100644 index 0000000000..13c220d42f --- /dev/null +++ b/Cronet/tests/cts/src/android/net/http/cts/BidirectionalStreamTest.kt @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.http.cts + +import android.content.Context +import android.net.http.BidirectionalStream +import android.net.http.HttpEngine +import android.net.http.cts.util.TestBidirectionalStreamCallback +import android.net.http.cts.util.TestBidirectionalStreamCallback.ResponseStep +import android.net.http.cts.util.assumeOKStatusCode +import android.net.http.cts.util.skipIfNoInternetConnection +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import kotlin.test.Test +import kotlin.test.assertEquals +import org.hamcrest.MatcherAssert +import org.hamcrest.Matchers +import org.junit.After +import org.junit.Before +import org.junit.runner.RunWith + +private const val URL = "https://source.android.com" + +/** + * This tests uses a non-hermetic server. Instead of asserting, assume the next callback. This way, + * if the request were to fail, the test would just be skipped instead of failing. + */ +@RunWith(AndroidJUnit4::class) +class BidirectionalStreamTest { + private val context: Context = ApplicationProvider.getApplicationContext() + private val callback = TestBidirectionalStreamCallback() + private val httpEngine = HttpEngine.Builder(context).build() + private var stream: BidirectionalStream? = null + + @Before + fun setUp() { + skipIfNoInternetConnection(context) + } + + @After + @Throws(Exception::class) + fun tearDown() { + // cancel active requests to enable engine shutdown. + stream?.let { + it.cancel() + callback.blockForDone() + } + httpEngine.shutdown() + } + + private fun createBidirectionalStreamBuilder(url: String): BidirectionalStream.Builder { + return httpEngine.newBidirectionalStreamBuilder(url, callback, callback.executor) + } + + @Test + @Throws(Exception::class) + fun testBidirectionalStream_GetStream_CompletesSuccessfully() { + stream = createBidirectionalStreamBuilder(URL).setHttpMethod("GET").build() + stream!!.start() + callback.assumeCallback(ResponseStep.ON_SUCCEEDED) + val info = callback.mResponseInfo + assumeOKStatusCode(info) + MatcherAssert.assertThat( + "Received byte count must be > 0", info.receivedByteCount, Matchers.greaterThan(0L)) + assertEquals("h2", info.negotiatedProtocol) + } +} diff --git a/Cronet/tests/cts/src/android/net/http/cts/util/TestBidirectionalStreamCallback.java b/Cronet/tests/cts/src/android/net/http/cts/util/TestBidirectionalStreamCallback.java index a2d18220a2..e82b24d7a1 100644 --- a/Cronet/tests/cts/src/android/net/http/cts/util/TestBidirectionalStreamCallback.java +++ b/Cronet/tests/cts/src/android/net/http/cts/util/TestBidirectionalStreamCallback.java @@ -16,10 +16,14 @@ package android.net.http.cts.util; +import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; +import static org.junit.Assume.assumeThat; +import static org.junit.Assume.assumeTrue; import android.net.http.BidirectionalStream; import android.net.http.HttpException; @@ -40,6 +44,7 @@ import java.util.concurrent.ThreadFactory; * an arbitrary step. */ public class TestBidirectionalStreamCallback extends BidirectionalStream.Callback { + private static final int TIMEOUT_MS = 12_000; public UrlResponseInfo mResponseInfo; public HttpException mError; @@ -135,6 +140,17 @@ public class TestBidirectionalStreamCallback extends BidirectionalStream.Callbac THROW_SYNC } + private boolean isTerminalCallback(ResponseStep step) { + switch (step) { + case ON_SUCCEEDED: + case ON_CANCELED: + case ON_FAILED: + return true; + default: + return false; + } + } + public TestBidirectionalStreamCallback() { mUseDirectExecutor = false; mDirectExecutor = null; @@ -154,8 +170,41 @@ public class TestBidirectionalStreamCallback extends BidirectionalStream.Callbac mFailureType = failureType; } - public void blockForDone() { - mDone.block(); + public boolean blockForDone() { + return mDone.block(TIMEOUT_MS); + } + + /** + * Waits for a terminal callback to complete execution before failing if the callback is not the + * expected one + * + * @param expectedStep the expected callback step + */ + public void expectCallback(ResponseStep expectedStep) { + if (isTerminalCallback(expectedStep)) { + assertTrue(String.format( + "Request timed out. Expected %s callback. Current callback is %s", + expectedStep, mResponseStep), + blockForDone()); + } + assertSame(expectedStep, mResponseStep); + } + + /** + * Waits for a terminal callback to complete execution before skipping the test if the callback + * is not the expected one + * + * @param expectedStep the expected callback step + */ + public void assumeCallback(ResponseStep expectedStep) { + if (isTerminalCallback(expectedStep)) { + assumeTrue( + String.format( + "Request timed out. Expected %s callback. Current callback is %s", + expectedStep, mResponseStep), + blockForDone()); + } + assumeThat(expectedStep, equalTo(mResponseStep)); } public void waitForNextReadStep() {