Move Cronet's MTS/CTS to external/cronet

* Cronet MTS / configuration changes continuously on each new import
that we do and coordinating two different repositories while doing an
import is unnecessarily added friction for which we wish to avoid.
Moving configuration to external/cronet will allow us to reduce test
divergence COMPLETELY which will make our import process  easier.

* The code under test exists under `external/cronet` which makes sense
that the testing modules should live next to the code under test.

* Moved CTS tests to external/cronet as the code under test lives in
external/cronet.

Test: TH
Bug: 304217500
Bug: 338358650
Change-Id: I7537985f66ba36169219472cc268fe8fd5b3c58d
This commit is contained in:
Mohannad Farrag 2024-05-02 10:47:59 +00:00
commit b824e0f2aa
30 changed files with 3 additions and 3517 deletions

View file

@ -1,8 +0,0 @@
# Bug component: 31808
set noparent
file:platform/packages/modules/Connectivity:main:/OWNERS_core_networking_xts
# TODO: Temp ownership to develop cronet CTS
colibie@google.com #{LAST_RESORT_SUGGESTION}
prohr@google.com #{LAST_RESORT_SUGGESTION}

View file

@ -1,79 +0,0 @@
// 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.
//
// Tests in this folder are included both in unit tests and CTS.
// They must be fast and stable, and exercise public or test APIs.
package {
default_team: "trendy_team_fwk_core_networking",
// See: http://go/android-license-faq
default_applicable_licenses: ["Android-Apache-2.0"],
}
// TODO: Consider merging with ConnectivityCoverageTests which is a collection of all
// Connectivity tests being used for coverage. This will depend on how far we decide to
// go with merging NetHttp and Tethering targets.
// Target used for coverage. Combines CTS tests and our MTS tests.
android_test {
name: "NetHttpCoverageTests",
enforce_default_target_sdk_version: true,
min_sdk_version: "30",
test_suites: [
"general-tests",
"mts-tethering",
],
static_libs: [
"modules-utils-native-coverage-listener",
"CtsNetHttpTestsLib",
"NetHttpTestsLibPreJarJar",
],
jarjar_rules: ":net-http-test-jarjar-rules",
compile_multilib: "both", // Include both the 32 and 64 bit versions
jni_libs: [
"cronet_aml_components_cronet_android_cronet_tests__testing",
"cronet_aml_third_party_netty_tcnative_netty_tcnative_so__testing",
"libnativecoverage",
],
data: [":cronet_javatests_resources"],
}
// MTS-only specific targets.
java_genrule {
name: "net-http-test-jarjar-rules",
tool_files: [
":NetHttpTestsLibPreJarJar{.jar}",
"jarjar_excludes.txt",
],
tools: [
"jarjar-rules-generator",
],
out: ["net_http_test_jarjar_rules.txt"],
cmd: "$(location jarjar-rules-generator) " +
"$(location :NetHttpTestsLibPreJarJar{.jar}) " +
"--prefix android.net.connectivity " +
"--excludes $(location jarjar_excludes.txt) " +
"--output $(out)",
}
android_library {
name: "NetHttpTestsLibPreJarJar",
static_libs: [
"cronet_aml_api_java",
"cronet_aml_java__testing",
"cronet_java_tests",
],
sdk_version: "module_current",
min_sdk_version: "30",
}

View file

@ -1,36 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ 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.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.android.net.http.tests.coverage">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET"/>
<application android:networkSecurityConfig="@xml/network_security_config"
tools:replace="android:label"
android:label="NetHttp coverage tests" >
<uses-library android:name="android.test.runner" />
</application>
<instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
android:targetPackage="com.android.net.http.tests.coverage"
android:label="NetHttp coverage tests">
</instrumentation>
</manifest>

View file

@ -1,59 +0,0 @@
<!--
~ 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.
-->
<configuration description="Runs coverage tests for NetHttp">
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="test-file-name" value="NetHttpCoverageTests.apk" />
<option name="install-arg" value="-t" />
</target_preparer>
<option name="test-tag" value="NetHttpCoverageTests" />
<target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
<option name="push-file" key="net" value="/storage/emulated/0/chromium_tests_root/net" />
<option name="push-file" key="test_server" value="/storage/emulated/0/chromium_tests_root/components/cronet/testing/test_server" />
</target_preparer>
<!-- Tethering/Connectivity is a SDK 30+ module however Cronet is installed on 31+ due to b/270049141. -->
<object type="module_controller"
class="com.android.tradefed.testtype.suite.module.Sdk31ModuleController" />
<!-- Only run NetHttpCoverageTests in MTS if the Tethering Mainline module is installed. -->
<object type="module_controller"
class="com.android.tradefed.testtype.suite.module.MainlineTestModuleController">
<option name="mainline-module-package-name" value="com.google.android.tethering" />
</object>
<option name="config-descriptor:metadata" key="mainline-param"
value="CaptivePortalLoginGoogle.apk+NetworkStackGoogle.apk+com.google.android.resolv.apex+com.google.android.tethering.apex" />
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="com.android.net.http.tests.coverage" />
<option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
<!-- b/298380508 -->
<option name="exclude-filter" value="org.chromium.net.CronetUrlRequestContextTest#testSetLibraryLoaderIsEnforcedByDefaultEmbeddedProvider" />
<!-- b/316559294 -->
<option name="exclude-filter" value="org.chromium.net.NQETest#testQuicDisabled" />
<!-- b/316559294 -->
<option name="exclude-filter" value="org.chromium.net.NQETest#testPrefsWriteRead" />
<!-- b/316554711-->
<option name="exclude-filter" value="org.chromium.net.NetworkChangesTest" />
<!-- b/316550794 -->
<option name="exclude-filter" value="org.chromium.net.impl.CronetLoggerTest#testEngineCreation" />
<!-- b/327182569 -->
<option name="exclude-filter" value="org.chromium.net.urlconnection.CronetURLStreamHandlerFactoryTest#testSetUrlStreamFactoryUsesCronetForNative" />
<option name="hidden-api-checks" value="false"/>
<option name="isolated-storage" value="false"/>
<option name="orchestrator" value="true"/>
<option
name="device-listeners"
value="com.android.modules.utils.testing.NativeCoverageHackInstrumentationListener" />
</test>
</configuration>

View file

@ -1,29 +0,0 @@
# Exclude some test prefixes, as they can't be found after being jarjared.
com\.android\.testutils\..+
# jarjar-gen can't handle some kotlin object expression, exclude packages that include them
androidx\..+
# don't jarjar netty as it does JNI
io\.netty\..+
kotlin\.test\..+
kotlin\.reflect\..+
org\.mockito\..+
# Do not jarjar the api classes
android\.net\..+
# cronet_tests.so is not jarjared and uses base classes. We can remove this when there's a
# separate java base target to depend on.
org\.chromium\.base\..+
J\.cronet_tests_N(\$.+)?
# don't jarjar automatically generated FooJni files.
org\.chromium\.net\..+Jni(\$.+)?
# Do not jarjar the tests and its utils as they also do JNI with cronet_tests.so
org\.chromium\.net\..*Test.*(\$.+)?
org\.chromium\.net\.NativeTestServer(\$.+)?
org\.chromium\.net\.MockUrlRequestJobFactory(\$.+)?
org\.chromium\.net\.QuicTestServer(\$.+)?
org\.chromium\.net\.MockCertVerifier(\$.+)?
org\.chromium\.net\.LogcatCapture(\$.+)?
org\.chromium\.net\.ReportingCollector(\$.+)?
org\.chromium\.net\.Http2TestServer(\$.+)?
org\.chromium\.net\.Http2TestHandler(\$.+)?

View file

@ -1,19 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIC/jCCAeagAwIBAgIUXOi6XoxnMUjJg4jeOwRhsdqEqEQwDQYJKoZIhvcNAQEL
BQAwFzEVMBMGA1UEAwwMVGVzdCBSb290IENBMB4XDTIzMDYwMTExMjcwMFoXDTMz
MDUyOTExMjcwMFowFzEVMBMGA1UEAwwMVGVzdCBSb290IENBMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEAl9xCMPMIvfmJWz25AG/VtgWbqNs67HXQbXWf
pDF2wjQpHVOYbfl7Zgly5O+5es1aUbJaGyZ9G6xuYSXKFnnYLoP7M86O05fQQBAj
K+IE5nO6136ksCAfxCFTFfn4vhPvK8Vba5rqox4WeIXYKvHYSoiHz0ELrnFOHcyN
Innyze7bLtkMCA1ShHpmvDCR+U3Uj6JwOfoirn29jjU/48/ORha7dcJYtYXk2eGo
RJfrtIx20tXAaKaGnXOCGYbEVXTeQkQPqKFVzqP7+KYS/Y8eNFV35ugpLNES+44T
bQ2QruTZdrNRjJkEoyiB/E53a0OUltB/R7Z0L0xstnKfsAf3OwIDAQABo0IwQDAP
BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUVdXNh2lk
51/6hMmz0Z+OpIe8+f0wDQYJKoZIhvcNAQELBQADggEBADNg7G8n6DUrQ5doXzm9
kOp5siX6iPs0zFReXKhIT1Gef63l3tb7AdPedF03aj9XkUt0shhNOGG5SK2k5KBQ
MJc9muYRCAyo2xMr3rFUQdI5B51SCy5HeAMralgTHXN0Hv+TH04YfRrACVmr+5ke
pH3bF1gYaT+Zy5/pHJnV5lcwS6/H44g9XXWIopjWCwbfzKxIuWofqL4fiToPSIYu
MCUI4bKZipcJT5O6rdz/S9lbgYVjOJ4HAoT2icNQqNMMfULKevmF8SdJzfNd35yn
tAKTROhIE2aQRVCclrjo/T3eyjWGGoJlGmxKbeCf/rXzcn1BRtk/UzLnbUFFlg5l
axw=
-----END CERTIFICATE-----

View file

@ -1,20 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ 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.
-->
<resources>
<bool name="is_running_in_aosp">true</bool>
</resources>

View file

@ -1,47 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2022 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.
-->
<network-security-config>
<base-config>
<trust-anchors>
<certificates src="@raw/quicroot"/>
<certificates src="system"/>
</trust-anchors>
</base-config>
<!-- Since Android 9 (API 28) cleartext support is disabled by default, this
causes some of our tests to fail (see crbug/1220357).
The following configs allow http requests for the domains used in these
tests.
TODO(stefanoduo): Figure out if we really need to use http for these tests
-->
<domain-config cleartextTrafficPermitted="true">
<!-- Used as the base URL by native test server (net::EmbeddedTestServer) -->
<domain includeSubdomains="true">127.0.0.1</domain>
<!-- Used by CronetHttpURLConnectionTest#testIOExceptionInterruptRethrown -->
<domain includeSubdomains="true">localhost</domain>
<!-- Used by CronetHttpURLConnectionTest#testBadIP -->
<domain includeSubdomains="true">0.0.0.0</domain>
<!-- Used by CronetHttpURLConnectionTest#testSetUseCachesFalse -->
<domain includeSubdomains="true">host-cache-test-host</domain>
<!-- Used by CronetHttpURLConnectionTest#testBadHostname -->
<domain includeSubdomains="true">this-weird-host-name-does-not-exist</domain>
<!-- Used by CronetUrlRequestContextTest#testHostResolverRules -->
<domain includeSubdomains="true">some-weird-hostname</domain>
</domain-config>
</network-security-config>

View file

@ -1,71 +0,0 @@
//
// Copyright (C) 2019 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 {
default_team: "trendy_team_fwk_core_networking",
default_applicable_licenses: ["Android-Apache-2.0"],
}
android_library {
name: "CtsNetHttpTestsLib",
defaults: [
"cts_defaults",
],
sdk_version: "test_current",
min_sdk_version: "30",
srcs: [
"src/**/*.java",
"src/**/*.kt",
],
static_libs: [
"androidx.test.ext.junit",
"ctstestrunner-axt",
"ctstestserver",
"hamcrest-library",
"junit",
"kotlin-test",
"mockito-target",
"net-tests-utils",
"truth",
],
libs: [
"android.test.base",
"androidx.annotation_annotation",
"framework-connectivity",
"org.apache.http.legacy",
],
lint: {
test: true,
},
}
android_test {
name: "CtsNetHttpTestCases",
defaults: [
"cts_defaults",
],
enforce_default_target_sdk_version: true,
sdk_version: "test_current",
min_sdk_version: "30",
static_libs: ["CtsNetHttpTestsLib"],
// Tag this as a cts test artifact
test_suites: [
"cts",
"general-tests",
"mts-tethering",
"mcts-tethering",
],
}

View file

@ -1,35 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
* Copyright (C) 2019 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.
*/
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android.net.http.cts">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<application android:networkSecurityConfig="@xml/network_security_config">
<uses-library android:name="android.test.runner"/>
</application>
<instrumentation
android:name="androidx.test.runner.AndroidJUnitRunner"
android:targetPackage="android.net.http.cts"
android:label="CTS tests of android.net.http">
</instrumentation>
</manifest>

View file

@ -1,38 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2019 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.
-->
<configuration description="Config for CTS Cronet test cases">
<option name="test-suite-tag" value="cts" />
<option name="config-descriptor:metadata" key="component" value="networking" />
<!-- Instant apps cannot create sockets. See b/264248246 -->
<option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
<option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
<option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
<option name="test-file-name" value="CtsNetHttpTestCases.apk" />
</target_preparer>
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="android.net.http.cts" />
<option name="runtime-hint" value="10s" />
</test>
<!-- Only run CtsNetHttpTestCases in MTS if the Tethering Mainline module is installed. -->
<object type="module_controller"
class="com.android.tradefed.testtype.suite.module.MainlineTestModuleController">
<option name="mainline-module-package-name" value="com.google.android.tethering" />
</object>
</configuration>

View file

@ -1,24 +0,0 @@
<!--
~ Copyright (C) 2022 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.
-->
<html>
<head>
<title>hello world</title>
</head>
<body>
<h3>hello world</h3><br>
</body>
</html>

View file

@ -1,23 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2022 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.
-->
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">localhost</domain>
</domain-config>
</network-security-config>

View file

@ -1,201 +0,0 @@
/*
* 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 android.os.Build
import androidx.test.core.app.ApplicationProvider
import com.android.testutils.DevSdkIgnoreRule
import com.android.testutils.DevSdkIgnoreRunner
import com.android.testutils.SkipPresubmit
import com.google.common.truth.Truth.assertThat
import kotlin.test.Test
import kotlin.test.assertEquals
import org.hamcrest.MatcherAssert
import org.hamcrest.Matchers
import org.junit.After
import org.junit.AssumptionViolatedException
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(DevSdkIgnoreRunner::class)
@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R)
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() {
httpEngine.shutdown()
}
private fun createBidirectionalStreamBuilder(url: String): BidirectionalStream.Builder {
return httpEngine.newBidirectionalStreamBuilder(url, callback.executor, callback)
}
@Test
@Throws(Exception::class)
@SkipPresubmit(reason = "b/293141085 Confirm non-flaky and move to presubmit after SLO")
fun testBidirectionalStream_GetStream_CompletesSuccessfully() {
stream = createBidirectionalStreamBuilder(URL).setHttpMethod("GET").build()
stream!!.start()
// We call to a real server and hence the server may not be reachable, cancel this stream
// and rethrow the exception before tearDown,
// otherwise shutdown would fail with active request error.
try {
callback.assumeCallback(ResponseStep.ON_SUCCEEDED)
} catch (e: AssumptionViolatedException) {
stream!!.cancel()
callback.blockForDone()
throw e
}
val info = callback.mResponseInfo
assumeOKStatusCode(info)
MatcherAssert.assertThat(
"Received byte count must be > 0", info.receivedByteCount, Matchers.greaterThan(0L))
assertEquals("h2", info.negotiatedProtocol)
}
@Test
@Throws(Exception::class)
fun testBidirectionalStream_getHttpMethod() {
val builder = createBidirectionalStreamBuilder(URL)
val method = "GET"
builder.setHttpMethod(method)
stream = builder.build()
assertThat(stream!!.getHttpMethod()).isEqualTo(method)
}
@Test
@Throws(Exception::class)
fun testBidirectionalStream_hasTrafficStatsTag() {
val builder = createBidirectionalStreamBuilder(URL)
builder.setTrafficStatsTag(10)
stream = builder.build()
assertThat(stream!!.hasTrafficStatsTag()).isTrue()
}
@Test
@Throws(Exception::class)
fun testBidirectionalStream_getTrafficStatsTag() {
val builder = createBidirectionalStreamBuilder(URL)
val trafficStatsTag = 10
builder.setTrafficStatsTag(trafficStatsTag)
stream = builder.build()
assertThat(stream!!.getTrafficStatsTag()).isEqualTo(trafficStatsTag)
}
@Test
@Throws(Exception::class)
fun testBidirectionalStream_hasTrafficStatsUid() {
val builder = createBidirectionalStreamBuilder(URL)
builder.setTrafficStatsUid(10)
stream = builder.build()
assertThat(stream!!.hasTrafficStatsUid()).isTrue()
}
@Test
@Throws(Exception::class)
fun testBidirectionalStream_getTrafficStatsUid() {
val builder = createBidirectionalStreamBuilder(URL)
val trafficStatsUid = 10
builder.setTrafficStatsUid(trafficStatsUid)
stream = builder.build()
assertThat(stream!!.getTrafficStatsUid()).isEqualTo(trafficStatsUid)
}
@Test
@Throws(Exception::class)
fun testBidirectionalStream_getHeaders_asList() {
val builder = createBidirectionalStreamBuilder(URL)
val expectedHeaders = mapOf(
"Authorization" to "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==",
"Max-Forwards" to "10",
"X-Client-Data" to "random custom header content").entries.toList()
for (header in expectedHeaders) {
builder.addHeader(header.key, header.value)
}
stream = builder.build()
assertThat(stream!!.getHeaders().getAsList()).containsAtLeastElementsIn(expectedHeaders)
}
@Test
@Throws(Exception::class)
fun testBidirectionalStream_getHeaders_asMap() {
val builder = createBidirectionalStreamBuilder(URL)
val expectedHeaders = mapOf(
"Authorization" to listOf("Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="),
"Max-Forwards" to listOf("10"),
"X-Client-Data" to listOf("random custom header content"))
for (header in expectedHeaders) {
builder.addHeader(header.key, header.value.get(0))
}
stream = builder.build()
assertThat(stream!!.getHeaders().getAsMap()).containsAtLeastEntriesIn(expectedHeaders)
}
@Test
@Throws(Exception::class)
fun testBidirectionalStream_getPriority() {
val builder = createBidirectionalStreamBuilder(URL)
val priority = BidirectionalStream.STREAM_PRIORITY_LOW
builder.setPriority(priority)
stream = builder.build()
assertThat(stream!!.getPriority()).isEqualTo(priority)
}
@Test
@Throws(Exception::class)
fun testBidirectionalStream_isDelayRequestHeadersUntilFirstFlushEnabled() {
val builder = createBidirectionalStreamBuilder(URL)
builder.setDelayRequestHeadersUntilFirstFlushEnabled(true)
stream = builder.build()
assertThat(stream!!.isDelayRequestHeadersUntilFirstFlushEnabled()).isTrue()
}
}

View file

@ -1,70 +0,0 @@
/*
* 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.CallbackException
import android.net.http.HttpEngine
import android.net.http.cts.util.HttpCtsTestServer
import android.net.http.cts.util.TestUrlRequestCallback
import android.net.http.cts.util.TestUrlRequestCallback.FailureType
import android.net.http.cts.util.TestUrlRequestCallback.ResponseStep
import android.os.Build
import androidx.test.core.app.ApplicationProvider
import com.android.testutils.DevSdkIgnoreRule
import com.android.testutils.DevSdkIgnoreRunner
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertIs
import kotlin.test.assertSame
import kotlin.test.assertTrue
import org.junit.runner.RunWith
@RunWith(DevSdkIgnoreRunner::class)
@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R)
class CallbackExceptionTest {
@Test
fun testCallbackException_returnsInputParameters() {
val message = "failed"
val cause = Throwable("exception")
val callbackException = object : CallbackException(message, cause) {}
assertEquals(message, callbackException.message)
assertSame(cause, callbackException.cause)
}
@Test
fun testCallbackException_thrownFromUrlRequest() {
val context: Context = ApplicationProvider.getApplicationContext()
val server = HttpCtsTestServer(context)
val httpEngine = HttpEngine.Builder(context).build()
val callback = TestUrlRequestCallback()
callback.setFailure(FailureType.THROW_SYNC, ResponseStep.ON_RESPONSE_STARTED)
val request = httpEngine
.newUrlRequestBuilder(server.successUrl, callback.executor, callback)
.build()
request.start()
callback.blockForDone()
assertTrue(request.isDone)
assertIs<CallbackException>(callback.mError)
server.shutdown()
httpEngine.shutdown()
}
}

View file

@ -1,71 +0,0 @@
/*
* 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.net.http.ConnectionMigrationOptions
import android.net.http.ConnectionMigrationOptions.MIGRATION_OPTION_ENABLED
import android.net.http.ConnectionMigrationOptions.MIGRATION_OPTION_UNSPECIFIED
import android.os.Build
import com.android.testutils.DevSdkIgnoreRule
import com.android.testutils.DevSdkIgnoreRunner
import kotlin.test.Test
import kotlin.test.assertEquals
import org.junit.runner.RunWith
@RunWith(DevSdkIgnoreRunner::class)
@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R)
class ConnectionMigrationOptionsTest {
@Test
fun testConnectionMigrationOptions_defaultValues() {
val options =
ConnectionMigrationOptions.Builder().build()
assertEquals(MIGRATION_OPTION_UNSPECIFIED, options.allowNonDefaultNetworkUsage)
assertEquals(MIGRATION_OPTION_UNSPECIFIED, options.defaultNetworkMigration)
assertEquals(MIGRATION_OPTION_UNSPECIFIED, options.pathDegradationMigration)
}
@Test
fun testConnectionMigrationOptions_enableDefaultNetworkMigration_returnSetValue() {
val options =
ConnectionMigrationOptions.Builder()
.setDefaultNetworkMigration(MIGRATION_OPTION_ENABLED)
.build()
assertEquals(MIGRATION_OPTION_ENABLED, options.defaultNetworkMigration)
}
@Test
fun testConnectionMigrationOptions_enablePathDegradationMigration_returnSetValue() {
val options =
ConnectionMigrationOptions.Builder()
.setPathDegradationMigration(MIGRATION_OPTION_ENABLED)
.build()
assertEquals(MIGRATION_OPTION_ENABLED, options.pathDegradationMigration)
}
@Test
fun testConnectionMigrationOptions_allowNonDefaultNetworkUsage_returnSetValue() {
val options =
ConnectionMigrationOptions.Builder()
.setAllowNonDefaultNetworkUsage(MIGRATION_OPTION_ENABLED).build()
assertEquals(MIGRATION_OPTION_ENABLED, options.allowNonDefaultNetworkUsage)
}
}

View file

@ -1,153 +0,0 @@
/*
* 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.net.http.DnsOptions
import android.net.http.DnsOptions.DNS_OPTION_ENABLED
import android.net.http.DnsOptions.DNS_OPTION_UNSPECIFIED
import android.os.Build
import com.android.testutils.DevSdkIgnoreRule
import com.android.testutils.DevSdkIgnoreRunner
import java.time.Duration
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertNotNull
import kotlin.test.assertNull
import org.junit.runner.RunWith
@RunWith(DevSdkIgnoreRunner::class)
@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R)
class DnsOptionsTest {
@Test
fun testDnsOptions_defaultValues() {
val options = DnsOptions.Builder().build()
assertEquals(DNS_OPTION_UNSPECIFIED, options.persistHostCache)
assertNull(options.persistHostCachePeriod)
assertEquals(DNS_OPTION_UNSPECIFIED, options.staleDns)
assertNull(options.staleDnsOptions)
assertEquals(DNS_OPTION_UNSPECIFIED, options.useHttpStackDnsResolver)
assertEquals(DNS_OPTION_UNSPECIFIED,
options.preestablishConnectionsToStaleDnsResults)
}
@Test
fun testDnsOptions_persistHostCache_returnSetValue() {
val options = DnsOptions.Builder()
.setPersistHostCache(DNS_OPTION_ENABLED)
.build()
assertEquals(DNS_OPTION_ENABLED, options.persistHostCache)
}
@Test
fun testDnsOptions_persistHostCachePeriod_returnSetValue() {
val period = Duration.ofMillis(12345)
val options = DnsOptions.Builder().setPersistHostCachePeriod(period).build()
assertEquals(period, options.persistHostCachePeriod)
}
@Test
fun testDnsOptions_enableStaleDns_returnSetValue() {
val options = DnsOptions.Builder()
.setStaleDns(DNS_OPTION_ENABLED)
.build()
assertEquals(DNS_OPTION_ENABLED, options.staleDns)
}
@Test
fun testDnsOptions_useHttpStackDnsResolver_returnsSetValue() {
val options = DnsOptions.Builder()
.setUseHttpStackDnsResolver(DNS_OPTION_ENABLED)
.build()
assertEquals(DNS_OPTION_ENABLED, options.useHttpStackDnsResolver)
}
@Test
fun testDnsOptions_preestablishConnectionsToStaleDnsResults_returnsSetValue() {
val options = DnsOptions.Builder()
.setPreestablishConnectionsToStaleDnsResults(DNS_OPTION_ENABLED)
.build()
assertEquals(DNS_OPTION_ENABLED,
options.preestablishConnectionsToStaleDnsResults)
}
@Test
fun testDnsOptions_setStaleDnsOptions_returnsSetValues() {
val staleOptions = DnsOptions.StaleDnsOptions.Builder()
.setAllowCrossNetworkUsage(DNS_OPTION_ENABLED)
.setFreshLookupTimeout(Duration.ofMillis(1234))
.build()
val options = DnsOptions.Builder()
.setStaleDns(DNS_OPTION_ENABLED)
.setStaleDnsOptions(staleOptions)
.build()
assertEquals(DNS_OPTION_ENABLED, options.staleDns)
assertEquals(staleOptions, options.staleDnsOptions)
}
@Test
fun testStaleDnsOptions_defaultValues() {
val options = DnsOptions.StaleDnsOptions.Builder().build()
assertEquals(DNS_OPTION_UNSPECIFIED, options.allowCrossNetworkUsage)
assertNull(options.freshLookupTimeout)
assertNull(options.maxExpiredDelay)
assertEquals(DNS_OPTION_UNSPECIFIED, options.useStaleOnNameNotResolved)
}
@Test
fun testStaleDnsOptions_allowCrossNetworkUsage_returnsSetValue() {
val options = DnsOptions.StaleDnsOptions.Builder()
.setAllowCrossNetworkUsage(DNS_OPTION_ENABLED).build()
assertEquals(DNS_OPTION_ENABLED, options.allowCrossNetworkUsage)
}
@Test
fun testStaleDnsOptions_freshLookupTimeout_returnsSetValue() {
val duration = Duration.ofMillis(12345)
val options = DnsOptions.StaleDnsOptions.Builder().setFreshLookupTimeout(duration).build()
assertNotNull(options.freshLookupTimeout)
assertEquals(duration, options.freshLookupTimeout!!)
}
@Test
fun testStaleDnsOptions_useStaleOnNameNotResolved_returnsSetValue() {
val options = DnsOptions.StaleDnsOptions.Builder()
.setUseStaleOnNameNotResolved(DNS_OPTION_ENABLED)
.build()
assertEquals(DNS_OPTION_ENABLED, options.useStaleOnNameNotResolved)
}
@Test
fun testStaleDnsOptions_maxExpiredDelayMillis_returnsSetValue() {
val duration = Duration.ofMillis(12345)
val options = DnsOptions.StaleDnsOptions.Builder().setMaxExpiredDelay(duration).build()
assertNotNull(options.maxExpiredDelay)
assertEquals(duration, options.maxExpiredDelay!!)
}
}

View file

@ -1,402 +0,0 @@
/*
* 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 static android.net.http.cts.util.TestUtilsKt.assertOKStatusCode;
import static android.net.http.cts.util.TestUtilsKt.assumeOKStatusCode;
import static android.net.http.cts.util.TestUtilsKt.skipIfNoInternetConnection;
import static com.google.common.truth.Truth.assertThat;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import android.content.Context;
import android.net.Network;
import android.net.http.ConnectionMigrationOptions;
import android.net.http.DnsOptions;
import android.net.http.HttpEngine;
import android.net.http.QuicOptions;
import android.net.http.UrlRequest;
import android.net.http.UrlResponseInfo;
import android.net.http.cts.util.HttpCtsTestServer;
import android.net.http.cts.util.TestUrlRequestCallback;
import android.net.http.cts.util.TestUrlRequestCallback.ResponseStep;
import android.os.Build;
import androidx.test.core.app.ApplicationProvider;
import com.android.testutils.DevSdkIgnoreRule;
import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import java.time.Instant;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Set;
@RunWith(DevSdkIgnoreRunner.class)
@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R)
public class HttpEngineTest {
private static final String HOST = "source.android.com";
private static final String URL = "https://" + HOST;
private HttpEngine.Builder mEngineBuilder;
private TestUrlRequestCallback mCallback;
private HttpCtsTestServer mTestServer;
private UrlRequest mRequest;
private HttpEngine mEngine;
private Context mContext;
@Before
public void setUp() throws Exception {
mContext = ApplicationProvider.getApplicationContext();
skipIfNoInternetConnection(mContext);
mEngineBuilder = new HttpEngine.Builder(mContext);
mCallback = new TestUrlRequestCallback();
mTestServer = new HttpCtsTestServer(mContext);
}
@After
public void tearDown() throws Exception {
if (mRequest != null) {
mRequest.cancel();
mCallback.blockForDone();
}
if (mEngine != null) {
mEngine.shutdown();
}
if (mTestServer != null) {
mTestServer.shutdown();
}
}
private boolean isQuic(String negotiatedProtocol) {
return negotiatedProtocol.startsWith("http/2+quic") || negotiatedProtocol.startsWith("h3");
}
@Test
public void testHttpEngine_Default() throws Exception {
mEngine = mEngineBuilder.build();
UrlRequest.Builder builder =
mEngine.newUrlRequestBuilder(URL, mCallback.getExecutor(), mCallback);
mRequest = builder.build();
mRequest.start();
// 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.
mCallback.assumeCallback(ResponseStep.ON_SUCCEEDED);
UrlResponseInfo info = mCallback.mResponseInfo;
assertOKStatusCode(info);
assertEquals("h2", info.getNegotiatedProtocol());
}
@Test
public void testHttpEngine_EnableHttpCache() {
String url = mTestServer.getCacheableTestDownloadUrl(
/* downloadId */ "cacheable-download",
/* numBytes */ 10);
mEngine =
mEngineBuilder
.setStoragePath(mContext.getApplicationInfo().dataDir)
.setEnableHttpCache(
HttpEngine.Builder.HTTP_CACHE_DISK, /* maxSize */ 100 * 1024)
.build();
UrlRequest.Builder builder =
mEngine.newUrlRequestBuilder(url, mCallback.getExecutor(), mCallback);
mRequest = builder.build();
mRequest.start();
mCallback.expectCallback(ResponseStep.ON_SUCCEEDED);
UrlResponseInfo info = mCallback.mResponseInfo;
assumeOKStatusCode(info);
assertFalse(info.wasCached());
mCallback = new TestUrlRequestCallback();
builder = mEngine.newUrlRequestBuilder(url, mCallback.getExecutor(), mCallback);
mRequest = builder.build();
mRequest.start();
mCallback.expectCallback(ResponseStep.ON_SUCCEEDED);
info = mCallback.mResponseInfo;
assertOKStatusCode(info);
assertTrue(info.wasCached());
}
@Test
public void testHttpEngine_DisableHttp2() throws Exception {
mEngine = mEngineBuilder.setEnableHttp2(false).build();
UrlRequest.Builder builder =
mEngine.newUrlRequestBuilder(URL, mCallback.getExecutor(), mCallback);
mRequest = builder.build();
mRequest.start();
// 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.
mCallback.assumeCallback(ResponseStep.ON_SUCCEEDED);
UrlResponseInfo info = mCallback.mResponseInfo;
assertOKStatusCode(info);
assertEquals("http/1.1", info.getNegotiatedProtocol());
}
@Test
public void testHttpEngine_EnablePublicKeyPinningBypassForLocalTrustAnchors() {
String url = mTestServer.getSuccessUrl();
// For known hosts, requests should succeed whether we're bypassing the local trust anchor
// or not.
mEngine = mEngineBuilder.setEnablePublicKeyPinningBypassForLocalTrustAnchors(false).build();
UrlRequest.Builder builder =
mEngine.newUrlRequestBuilder(url, mCallback.getExecutor(), mCallback);
mRequest = builder.build();
mRequest.start();
mCallback.expectCallback(ResponseStep.ON_SUCCEEDED);
mEngine.shutdown();
mEngine = mEngineBuilder.setEnablePublicKeyPinningBypassForLocalTrustAnchors(true).build();
mCallback = new TestUrlRequestCallback();
builder = mEngine.newUrlRequestBuilder(url, mCallback.getExecutor(), mCallback);
mRequest = builder.build();
mRequest.start();
mCallback.expectCallback(ResponseStep.ON_SUCCEEDED);
// TODO(b/270918920): We should also test with a certificate not present in the device's
// trusted store.
// This requires either:
// * Mocking the underlying CertificateVerifier.
// * Or, having the server return a root certificate not present in the device's trusted
// store.
// The former doesn't make sense for a CTS test as it would depend on the underlying
// implementation. The latter is something we should support once we write a proper test
// server.
}
private byte[] generateSha256() {
byte[] sha256 = new byte[32];
Arrays.fill(sha256, (byte) 58);
return sha256;
}
private Instant instantInFuture(int secondsIntoFuture) {
Calendar cal = Calendar.getInstance();
cal.add(Calendar.SECOND, secondsIntoFuture);
return cal.getTime().toInstant();
}
@Test
public void testHttpEngine_AddPublicKeyPins() {
// CtsTestServer, when set in SslMode.NO_CLIENT_AUTH (required to trigger
// certificate verification, needed by this test), uses a certificate that
// doesn't match the hostname. For this reason, CtsTestServer cannot be used
// by this test.
Instant expirationInstant = instantInFuture(/* secondsIntoFuture */ 100);
boolean includeSubdomains = true;
Set<byte[]> pinsSha256 = Set.of(generateSha256());
mEngine = mEngineBuilder.addPublicKeyPins(
HOST, pinsSha256, includeSubdomains, expirationInstant).build();
UrlRequest.Builder builder =
mEngine.newUrlRequestBuilder(URL, mCallback.getExecutor(), mCallback);
mRequest = builder.build();
mRequest.start();
mCallback.expectCallback(ResponseStep.ON_FAILED);
assertNotNull("Expected an error", mCallback.mError);
}
@Test
public void testHttpEngine_EnableQuic() throws Exception {
String url = mTestServer.getSuccessUrl();
mEngine = mEngineBuilder.setEnableQuic(true).addQuicHint(HOST, 443, 443).build();
UrlRequest.Builder builder =
mEngine.newUrlRequestBuilder(url, mCallback.getExecutor(), mCallback);
mRequest = builder.build();
mRequest.start();
mCallback.expectCallback(ResponseStep.ON_SUCCEEDED);
UrlResponseInfo info = mCallback.mResponseInfo;
assertOKStatusCode(info);
}
@Test
public void testHttpEngine_GetDefaultUserAgent() throws Exception {
assertThat(mEngineBuilder.getDefaultUserAgent(), containsString("AndroidHttpClient"));
assertThat(mEngineBuilder.getDefaultUserAgent()).contains(HttpEngine.getVersionString());
}
@Test
public void testHttpEngine_requestUsesDefaultUserAgent() throws Exception {
mEngine = mEngineBuilder.build();
String url = mTestServer.getUserAgentUrl();
UrlRequest request =
mEngine.newUrlRequestBuilder(url, mCallback.getExecutor(), mCallback).build();
request.start();
mCallback.expectCallback(ResponseStep.ON_SUCCEEDED);
UrlResponseInfo info = mCallback.mResponseInfo;
assertOKStatusCode(info);
String receivedUserAgent = extractUserAgent(mCallback.mResponseAsString);
assertThat(receivedUserAgent).isEqualTo(mEngineBuilder.getDefaultUserAgent());
}
@Test
public void testHttpEngine_requestUsesCustomUserAgent() throws Exception {
String userAgent = "CtsTests User Agent";
mEngine =
new HttpEngine.Builder(ApplicationProvider.getApplicationContext())
.setUserAgent(userAgent)
.build();
String url = mTestServer.getUserAgentUrl();
UrlRequest request =
mEngine.newUrlRequestBuilder(url, mCallback.getExecutor(), mCallback).build();
request.start();
mCallback.expectCallback(ResponseStep.ON_SUCCEEDED);
UrlResponseInfo info = mCallback.mResponseInfo;
assertOKStatusCode(info);
String receivedUserAgent = extractUserAgent(mCallback.mResponseAsString);
assertThat(receivedUserAgent).isEqualTo(userAgent);
}
private static String extractUserAgent(String userAgentResponseBody) {
// If someone wants to be evil and have the title HTML tag a part of the user agent,
// they'll have to fix this method :)
return userAgentResponseBody.replaceFirst(".*<title>", "").replaceFirst("</title>.*", "");
}
@Test
public void testHttpEngine_bindToNetwork() throws Exception {
// Create a fake Android.net.Network. Since that network doesn't exist, binding to
// that should end up in a failed request.
Network mockNetwork = Mockito.mock(Network.class);
Mockito.when(mockNetwork.getNetworkHandle()).thenReturn(123L);
String url = mTestServer.getSuccessUrl();
mEngine = mEngineBuilder.build();
mEngine.bindToNetwork(mockNetwork);
UrlRequest.Builder builder =
mEngine.newUrlRequestBuilder(url, mCallback.getExecutor(), mCallback);
mRequest = builder.build();
mRequest.start();
mCallback.expectCallback(ResponseStep.ON_FAILED);
}
@Test
public void testHttpEngine_unbindFromNetwork() throws Exception {
// Create a fake Android.net.Network. Since that network doesn't exist, binding to
// that should end up in a failed request.
Network mockNetwork = Mockito.mock(Network.class);
Mockito.when(mockNetwork.getNetworkHandle()).thenReturn(123L);
String url = mTestServer.getSuccessUrl();
mEngine = mEngineBuilder.build();
// Bind to the fake network but then unbind. This should result in a successful
// request.
mEngine.bindToNetwork(mockNetwork);
mEngine.bindToNetwork(null);
UrlRequest.Builder builder =
mEngine.newUrlRequestBuilder(url, mCallback.getExecutor(), mCallback);
mRequest = builder.build();
mRequest.start();
mCallback.expectCallback(ResponseStep.ON_SUCCEEDED);
UrlResponseInfo info = mCallback.mResponseInfo;
assertOKStatusCode(info);
}
@Test
public void testHttpEngine_setConnectionMigrationOptions_requestSucceeds() {
ConnectionMigrationOptions options = new ConnectionMigrationOptions.Builder().build();
mEngine = mEngineBuilder.setConnectionMigrationOptions(options).build();
UrlRequest.Builder builder =
mEngine.newUrlRequestBuilder(
mTestServer.getSuccessUrl(), mCallback.getExecutor(), mCallback);
mRequest = builder.build();
mRequest.start();
mCallback.expectCallback(ResponseStep.ON_SUCCEEDED);
UrlResponseInfo info = mCallback.mResponseInfo;
assertOKStatusCode(info);
}
@Test
public void testHttpEngine_setDnsOptions_requestSucceeds() {
DnsOptions options = new DnsOptions.Builder().build();
mEngine = mEngineBuilder.setDnsOptions(options).build();
UrlRequest.Builder builder =
mEngine.newUrlRequestBuilder(
mTestServer.getSuccessUrl(), mCallback.getExecutor(), mCallback);
mRequest = builder.build();
mRequest.start();
mCallback.expectCallback(ResponseStep.ON_SUCCEEDED);
UrlResponseInfo info = mCallback.mResponseInfo;
assertOKStatusCode(info);
}
@Test
public void getVersionString_notEmpty() {
assertThat(HttpEngine.getVersionString()).isNotEmpty();
}
@Test
public void testHttpEngine_SetQuicOptions_RequestSucceedsWithQuic() throws Exception {
String url = mTestServer.getSuccessUrl();
QuicOptions options = new QuicOptions.Builder().build();
mEngine = mEngineBuilder
.setEnableQuic(true)
.addQuicHint(HOST, 443, 443)
.setQuicOptions(options)
.build();
UrlRequest.Builder builder =
mEngine.newUrlRequestBuilder(url, mCallback.getExecutor(), mCallback);
mRequest = builder.build();
mRequest.start();
mCallback.expectCallback(ResponseStep.ON_SUCCEEDED);
UrlResponseInfo info = mCallback.mResponseInfo;
assertOKStatusCode(info);
}
@Test
public void testHttpEngine_enableBrotli_brotliAdvertised() {
mEngine = mEngineBuilder.setEnableBrotli(true).build();
mRequest =
mEngine.newUrlRequestBuilder(
mTestServer.getEchoHeadersUrl(), mCallback.getExecutor(), mCallback)
.build();
mRequest.start();
mCallback.assumeCallback(ResponseStep.ON_SUCCEEDED);
UrlResponseInfo info = mCallback.mResponseInfo;
assertThat(info.getHeaders().getAsMap().get("x-request-header-Accept-Encoding").toString())
.contains("br");
assertOKStatusCode(info);
}
}

View file

@ -1,65 +0,0 @@
/*
* 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.net.http.HttpEngine
import android.net.http.NetworkException
import android.net.http.cts.util.TestUrlRequestCallback
import android.os.Build
import androidx.test.core.app.ApplicationProvider
import com.android.testutils.DevSdkIgnoreRule
import com.android.testutils.DevSdkIgnoreRunner
import kotlin.test.assertEquals
import kotlin.test.assertIs
import kotlin.test.assertSame
import kotlin.test.assertTrue
import org.junit.Test
import org.junit.runner.RunWith
@RunWith(DevSdkIgnoreRunner::class)
@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R)
class NetworkExceptionTest {
@Test
fun testNetworkException_returnsInputParameters() {
val message = "failed"
val cause = Throwable("thrown")
val networkException =
object : NetworkException(message, cause) {
override fun getErrorCode() = 0
override fun isImmediatelyRetryable() = false
}
assertEquals(message, networkException.message)
assertSame(cause, networkException.cause)
}
@Test
fun testNetworkException_thrownFromUrlRequest() {
val httpEngine = HttpEngine.Builder(ApplicationProvider.getApplicationContext()).build()
val callback = TestUrlRequestCallback()
val request =
httpEngine.newUrlRequestBuilder("http://localhost", callback.executor, callback).build()
request.start()
callback.blockForDone()
assertTrue(request.isDone)
assertIs<NetworkException>(callback.mError)
httpEngine.shutdown()
}
}

View file

@ -1,46 +0,0 @@
/*
* 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.net.http.QuicException
import android.os.Build
import com.android.testutils.DevSdkIgnoreRule
import com.android.testutils.DevSdkIgnoreRunner
import kotlin.test.Test
import kotlin.test.assertEquals
import org.junit.runner.RunWith
@RunWith(DevSdkIgnoreRunner::class)
@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R)
class QuicExceptionTest {
@Test
fun testQuicException_returnsInputParameters() {
val message = "failed"
val cause = Throwable("thrown")
val quicException =
object : QuicException(message, cause) {
override fun getErrorCode() = 0
override fun isImmediatelyRetryable() = false
}
assertEquals(message, quicException.message)
assertEquals(cause, quicException.cause)
}
// TODO: add test for QuicException triggered from HttpEngine
}

Some files were not shown because too many files have changed in this diff Show more